1b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/*
2b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ProGuard -- shrinking, optimization, obfuscation, and preverification
3b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *             of Java bytecode.
4b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
5b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
6b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
7b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is free software; you can redistribute it and/or modify it
8b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * under the terms of the GNU General Public License as published by the Free
9b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Software Foundation; either version 2 of the License, or (at your option)
10b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * any later version.
11b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
12b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is distributed in the hope that it will be useful, but WITHOUT
13b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * more details.
16b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
17b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * You should have received a copy of the GNU General Public License along
18b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * with this program; if not, write to the Free Software Foundation, Inc.,
19b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */
21b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopackage proguard.gui;
22b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
23b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.*;
24b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.util.ListUtil;
25b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
26b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport javax.swing.*;
27b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport java.awt.*;
28b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport java.awt.event.*;
29b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport java.io.File;
30b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport java.util.List;
31b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
32b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/**
33b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This <code>ListPanel</code> allows the user to add, edit, filter, move, and
34b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * remove ClassPathEntry objects in a ClassPath object.
35b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
36b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @author Eric Lafortune
37b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */
38b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoclass ClassPathPanel extends ListPanel
39b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato{
40b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private final JFrame       owner;
41b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private final boolean      inputAndOutput;
42b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private final JFileChooser chooser;
43b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private final FilterDialog filterDialog;
44b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
45b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
46b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public ClassPathPanel(JFrame owner, boolean inputAndOutput)
47b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
48b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        super();
49b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
50b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        super.firstSelectionButton = inputAndOutput ? 3 : 2;
51b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
52b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        this.owner          = owner;
53b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        this.inputAndOutput = inputAndOutput;
54b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
55b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        list.setCellRenderer(new MyListCellRenderer());
56b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
57b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        chooser = new JFileChooser("");
58b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        chooser.setMultiSelectionEnabled(true);
59b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
60b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        chooser.addChoosableFileFilter(
61b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            new ExtensionFileFilter(msg("jarWarEarZipExtensions"),
62b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                    new String[] { ".jar", ".war", ".ear", ".zip" }));
63b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        chooser.setApproveButtonText(msg("ok"));
64b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
65b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        filterDialog = new FilterDialog(owner, msg("enterFilter"));
66b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
67b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        addAddButton(inputAndOutput, false);
68b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (inputAndOutput)
69b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
70b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            addAddButton(inputAndOutput, true);
71b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
72b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        addEditButton();
73b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        addFilterButton();
74b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        addRemoveButton();
75b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        addUpButton();
76b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        addDownButton();
77b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
78b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        enableSelectionButtons();
79b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
80b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
81b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
82b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected void addAddButton(boolean       inputAndOutput,
83b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                final boolean isOutput)
84b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
85b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        JButton addButton = new JButton(msg(inputAndOutput ?
86b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                            isOutput       ? "addOutput" :
87b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                             "addInput" :
88b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                             "add"));
89b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        addButton.addActionListener(new ActionListener()
90b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
91b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            public void actionPerformed(ActionEvent e)
92b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
93b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                chooser.setDialogTitle(msg("addJars"));
94b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                chooser.setSelectedFile(null);
95b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                chooser.setSelectedFiles(null);
96b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
97b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                int returnValue = chooser.showOpenDialog(owner);
98b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                if (returnValue == JFileChooser.APPROVE_OPTION)
99b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                {
100b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    File[] selectedFiles = chooser.getSelectedFiles();
101b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    ClassPathEntry[] entries = classPathEntries(selectedFiles, isOutput);
102b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
103b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    // Add the new elements.
104b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    addElements(entries);
105b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                }
106b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
107b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        });
108b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
109b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        addButton(tip(addButton, inputAndOutput ?
110b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                 isOutput       ? "addOutputTip" :
111b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                  "addInputTip" :
112b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                  "addTip"));
113b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
114b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
115b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
116b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected void addEditButton()
117b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
118b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        JButton editButton = new JButton(msg("edit"));
119b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        editButton.addActionListener(new ActionListener()
120b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
121b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            public void actionPerformed(ActionEvent e)
122b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
123b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                boolean isOutput = false;
124b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
125b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                int[] selectedIndices = list.getSelectedIndices();
126b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
127b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                // Copy the Object array into a File array.
128b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                File[] selectedFiles = new File[selectedIndices.length];
129b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                for (int index = 0; index < selectedFiles.length; index++)
130b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                {
131b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    ClassPathEntry entry =
132b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                        (ClassPathEntry)listModel.getElementAt(selectedIndices[index]);
133b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
134b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    isOutput = entry.isOutput();
135b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
136b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    selectedFiles[index] = entry.getFile();
137b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                }
138b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
139b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                chooser.setDialogTitle(msg("chooseJars"));
140b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
141b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                // Up to JDK 1.3.1, setSelectedFiles doesn't show in the file
142b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                // chooser, so we just use setSelectedFile first. It also sets
143b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                // the current directory.
144b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                chooser.setSelectedFile(selectedFiles[0]);
145b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                chooser.setSelectedFiles(selectedFiles);
146b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
147b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                int returnValue = chooser.showOpenDialog(owner);
148b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                if (returnValue == JFileChooser.APPROVE_OPTION)
149b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                {
150b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    selectedFiles = chooser.getSelectedFiles();
151b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    ClassPathEntry[] entries = classPathEntries(selectedFiles, isOutput);
152b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
153b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    // If there are the same number of files selected now as
154b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    // there were before, we can just replace the old ones.
155b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    if (selectedIndices.length == selectedFiles.length)
156b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    {
157b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                        // Replace the old elements.
158b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                        setElementsAt(entries, selectedIndices);
159b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    }
160b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    else
161b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    {
162b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                        // Remove the old elements.
163b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                        removeElementsAt(selectedIndices);
164b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
165b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                        // Add the new elements.
166b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                        addElements(entries);
167b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    }
168b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                }
169b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
170b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        });
171b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
172b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        addButton(tip(editButton, "editTip"));
173b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
174b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
175b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
176b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    protected void addFilterButton()
177b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
178b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        JButton filterButton = new JButton(msg("filter"));
179b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        filterButton.addActionListener(new ActionListener()
180b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
181b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            public void actionPerformed(ActionEvent e)
182b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
183b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                if (!list.isSelectionEmpty())
184b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                {
185b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    int[] selectedIndices = list.getSelectedIndices();
186b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
187b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    // Put the filters of the first selected entry in the dialog.
188b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    getFiltersFrom(selectedIndices[0]);
189b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
190b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    int returnValue = filterDialog.showDialog();
191b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    if (returnValue == FilterDialog.APPROVE_OPTION)
192b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    {
193b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                        // Apply the entered filters to all selected entries.
194b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                        setFiltersAt(selectedIndices);
195b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    }
196b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                }
197b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
198b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        });
199b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
200b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        addButton(tip(filterButton, "filterTip"));
201b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
202b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
203b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
204b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
205b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Sets the ClassPath to be represented in this panel.
206b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
207b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void setClassPath(ClassPath classPath)
208b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
209b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        listModel.clear();
210b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
211b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (classPath != null)
212b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
213b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            for (int index = 0; index < classPath.size(); index++)
214b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
215b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                listModel.addElement(classPath.get(index));
216b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
217b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
218b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
219b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Make sure the selection buttons are properly enabled,
220b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // since the clear method doesn't seem to notify the listener.
221b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        enableSelectionButtons();
222b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
223b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
224b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
225b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
226b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Returns the ClassPath currently represented in this panel.
227b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
228b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public ClassPath getClassPath()
229b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
230b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        int size = listModel.size();
231b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (size == 0)
232b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
233b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            return null;
234b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
235b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
236b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        ClassPath classPath = new ClassPath();
237b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        for (int index = 0; index < size; index++)
238b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
239b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            classPath.add((ClassPathEntry)listModel.get(index));
240b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
241b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
242b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return classPath;
243b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
244b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
245b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
246b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
247b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Converts the given array of File objects into a corresponding array of
248b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * ClassPathEntry objects.
249b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
250b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private ClassPathEntry[] classPathEntries(File[] files, boolean isOutput)
251b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
252b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        ClassPathEntry[] entries = new ClassPathEntry[files.length];
253b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        for (int index = 0; index < entries.length; index++)
254b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
255b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            entries[index] = new ClassPathEntry(files[index], isOutput);
256b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
257b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return entries;
258b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
259b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
260b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
261b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
262b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Sets up the filter dialog with the filters from the specified class path
263b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * entry.
264b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
265b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private void getFiltersFrom(int index)
266b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
267b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        ClassPathEntry firstEntry = (ClassPathEntry)listModel.get(index);
268b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
269b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        filterDialog.setFilter(firstEntry.getFilter());
270b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        filterDialog.setJarFilter(firstEntry.getJarFilter());
271b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        filterDialog.setWarFilter(firstEntry.getWarFilter());
272b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        filterDialog.setEarFilter(firstEntry.getEarFilter());
273b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        filterDialog.setZipFilter(firstEntry.getZipFilter());
274b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
275b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
276b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
277b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
278b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Applies the entered filter to the specified class path entries.
279b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Any previously set filters are discarded.
280b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
281b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private void setFiltersAt(int[] indices)
282b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
283b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        for (int index = indices.length - 1; index >= 0; index--)
284b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
285b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            ClassPathEntry entry = (ClassPathEntry)listModel.get(indices[index]);
286b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            entry.setFilter(filterDialog.getFilter());
287b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            entry.setJarFilter(filterDialog.getJarFilter());
288b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            entry.setWarFilter(filterDialog.getWarFilter());
289b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            entry.setEarFilter(filterDialog.getEarFilter());
290b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            entry.setZipFilter(filterDialog.getZipFilter());
291b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
292b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
293b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Make sure they are selected and thus repainted.
294b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        list.setSelectedIndices(indices);
295b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
296b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
297b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
298b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
299b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Attaches the tool tip from the GUI resources that corresponds to the
300b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * given key, to the given component.
301b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
302b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private static JComponent tip(JComponent component, String messageKey)
303b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
304b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        component.setToolTipText(msg(messageKey));
305b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
306b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return component;
307b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
308b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
309b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
310b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
311b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Returns the message from the GUI resources that corresponds to the given
312b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * key.
313b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
314b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private static String msg(String messageKey)
315b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
316b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato         return GUIResources.getMessage(messageKey);
317b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
318b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
319b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
320b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
321b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * This ListCellRenderer renders ClassPathEntry objects.
322b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
323b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private class MyListCellRenderer implements ListCellRenderer
324b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
325b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        private static final String ARROW_IMAGE_FILE = "arrow.gif";
326b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
327b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        private final JPanel cellPanel    = new JPanel(new GridBagLayout());
328b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        private final JLabel iconLabel    = new JLabel("", JLabel.RIGHT);
329b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        private final JLabel jarNameLabel = new JLabel("", JLabel.RIGHT);
330b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        private final JLabel filterLabel  = new JLabel("", JLabel.RIGHT);
331b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
332b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        private final Icon arrowIcon;
333b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
334b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
335b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        public MyListCellRenderer()
336b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
337b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            GridBagConstraints jarNameLabelConstraints = new GridBagConstraints();
338b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            jarNameLabelConstraints.anchor             = GridBagConstraints.WEST;
339b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            jarNameLabelConstraints.insets             = new Insets(1, 2, 1, 2);
340b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
341b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            GridBagConstraints filterLabelConstraints  = new GridBagConstraints();
342b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            filterLabelConstraints.gridwidth           = GridBagConstraints.REMAINDER;
343b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            filterLabelConstraints.fill                = GridBagConstraints.HORIZONTAL;
344b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            filterLabelConstraints.weightx             = 1.0;
345b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            filterLabelConstraints.anchor              = GridBagConstraints.EAST;
346b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            filterLabelConstraints.insets              = jarNameLabelConstraints.insets;
347b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
348b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            arrowIcon = new ImageIcon(Toolkit.getDefaultToolkit().getImage(this.getClass().getResource(ARROW_IMAGE_FILE)));
349b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
350b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            cellPanel.add(iconLabel,    jarNameLabelConstraints);
351b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            cellPanel.add(jarNameLabel, jarNameLabelConstraints);
352b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            cellPanel.add(filterLabel,  filterLabelConstraints);
353b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
354b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
355b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
356b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Implementations for ListCellRenderer.
357b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
358b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        public Component getListCellRendererComponent(JList   list,
359b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                      Object  value,
360b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                      int     index,
361b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                      boolean isSelected,
362b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                      boolean cellHasFocus)
363b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
364b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            ClassPathEntry entry = (ClassPathEntry)value;
365b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
366b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Prepend an arrow to the output entries.
367b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (inputAndOutput && entry.isOutput())
368b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
369b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                iconLabel.setIcon(arrowIcon);
370b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
371b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            else
372b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
373b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                iconLabel.setIcon(null);
374b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
375b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
376b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Set the entry name text.
377b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            jarNameLabel.setText(entry.getName());
378b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
379b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Set the filter text.
380b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            StringBuffer filter = null;
381b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            filter = appendFilter(filter, entry.getZipFilter());
382b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            filter = appendFilter(filter, entry.getEarFilter());
383b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            filter = appendFilter(filter, entry.getWarFilter());
384b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            filter = appendFilter(filter, entry.getJarFilter());
385b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            filter = appendFilter(filter, entry.getFilter());
386b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
387b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (filter != null)
388b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
389b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                filter.append(')');
390b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
391b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
392b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            filterLabel.setText(filter != null ? filter.toString() : "");
393b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
394b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Set the colors.
395b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (isSelected)
396b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
397b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                cellPanel.setBackground(list.getSelectionBackground());
398b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                jarNameLabel.setForeground(list.getSelectionForeground());
399b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                filterLabel.setForeground(list.getSelectionForeground());
400b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
401b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            else
402b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
403b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                cellPanel.setBackground(list.getBackground());
404b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                jarNameLabel.setForeground(list.getForeground());
405b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                filterLabel.setForeground(list.getForeground());
406b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
407b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
408b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Make the font color red if this is an input file that can't be read.
409b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (!(inputAndOutput && entry.isOutput()) &&
410b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                !entry.getFile().canRead())
411b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
412b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                jarNameLabel.setForeground(Color.red);
413b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
414b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
415b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            cellPanel.setOpaque(true);
416b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
417b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            return cellPanel;
418b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
419b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
420b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
421b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        private StringBuffer appendFilter(StringBuffer filter, List additionalFilter)
422b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
423b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (filter != null)
424b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
425b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                filter.append(';');
426b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
427b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
428b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (additionalFilter != null)
429b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
430b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                if (filter == null)
431b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                {
432b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    filter = new StringBuffer().append('(');
433b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                }
434b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
435b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                filter.append(ListUtil.commaSeparatedString(additionalFilter));
436b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
437b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
438b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            return filter;
439b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
440b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
441b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato}
442