25 package org.sleuthkit.autopsy.filesearch;
27 import java.awt.BorderLayout;
28 import java.awt.Component;
29 import java.awt.Cursor;
30 import java.awt.Dimension;
31 import java.awt.event.ActionEvent;
32 import java.awt.event.ActionListener;
33 import java.util.ArrayList;
34 import java.util.Collection;
35 import java.util.Collections;
36 import java.util.List;
37 import java.util.logging.Level;
39 import org.openide.util.NbBundle;
41 import javax.swing.BoxLayout;
42 import javax.swing.JButton;
43 import javax.swing.JLabel;
44 import javax.swing.JPanel;
45 import javax.swing.border.EmptyBorder;
46 import org.openide.DialogDisplayer;
47 import org.openide.NotifyDescriptor;
48 import org.openide.windows.TopComponent;
61 class FileSearchPanel
extends javax.swing.JPanel {
63 private List<FilterArea> filterAreas =
new ArrayList<FilterArea>();
64 private JButton searchButton;
65 private static int resultWindowCount = 0;
70 public FileSearchPanel() {
72 customizeComponents();
79 private void customizeComponents() {
81 this.setLayout(
new BorderLayout());
83 JPanel filterPanel =
new JPanel();
84 filterPanel.setLayout(
new BoxLayout(filterPanel, BoxLayout.Y_AXIS));
85 filterPanel.setBorder(
new EmptyBorder(10, 10, 10, 10));
87 this.add(filterPanel, BorderLayout.CENTER);
89 JLabel label =
new JLabel(NbBundle.getMessage(
this.getClass(),
"FileSearchPanel.custComp.label.text"));
90 label.setAlignmentX(Component.LEFT_ALIGNMENT);
91 label.setBorder(
new EmptyBorder(0, 0, 10, 0));
92 filterPanel.add(label);
95 this.filterAreas.add(
new FilterArea(NbBundle.getMessage(
this.getClass(),
"FileSearchPanel.filterTitle.name"),
new NameSearchFilter()));
97 List<FileSearchFilter> metadataFilters =
new ArrayList<FileSearchFilter>();
98 metadataFilters.add(
new SizeSearchFilter());
99 metadataFilters.add(
new DateSearchFilter());
100 this.filterAreas.add(
new FilterArea(NbBundle.getMessage(
this.getClass(),
"FileSearchPanel.filterTitle.metadata"), metadataFilters));
102 this.filterAreas.add(
new FilterArea(NbBundle.getMessage(
this.getClass(),
"FileSearchPanel.filterTitle.knownStatus"),
new KnownStatusSearchFilter()));
104 for (FilterArea fa : this.filterAreas) {
105 fa.setMaximumSize(
new Dimension(Integer.MAX_VALUE, fa.getMinimumSize().height));
106 fa.setAlignmentX(Component.LEFT_ALIGNMENT);
111 this.searchButton =
new JButton(NbBundle.getMessage(
this.getClass(),
"FileSearchPanel.searchButton.text"));
112 this.searchButton.setAlignmentX(Component.LEFT_ALIGNMENT);
113 filterPanel.add(searchButton);
115 addListenerToAll(
new ActionListener() {
117 public void actionPerformed(ActionEvent e) {
126 private boolean anyFiltersEnabled() {
127 for (FileSearchFilter filter : this.getFilters()) {
128 if (filter.isEnabled()) {
140 private void search() {
142 this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
144 if (this.anyFiltersEnabled()) {
145 String title = NbBundle.getMessage(this.getClass(),
"FileSearchPanel.search.results.title", ++resultWindowCount);
146 String pathText = NbBundle.getMessage(this.getClass(),
"FileSearchPanel.search.results.pathText");
149 Case currentCase = Case.getCurrentCase();
150 long totalMatches = 0;
151 List<AbstractFile> contentList = null;
153 SleuthkitCase tskDb = currentCase.getSleuthkitCase();
155 contentList = tskDb.findAllFilesWhere(this.getQuery());
157 }
catch (TskCoreException ex) {
158 Logger logger = Logger.getLogger(this.getClass().getName());
159 logger.log(Level.WARNING,
"Error while trying to get the number of matches.", ex);
162 if (contentList == null) {
163 contentList = Collections.<AbstractFile>emptyList();
166 final TopComponent searchResultWin = DataResultTopComponent.createInstance(title, pathText,
167 new TableFilterNode(
new SearchNode(contentList),
true), contentList.size());
169 searchResultWin.requestActive();
176 if (totalMatches > 10000) {
178 String msg = NbBundle.getMessage(this.getClass(),
"FileSearchPanel.search.results.msg", totalMatches);
179 String details = NbBundle.getMessage(this.getClass(),
"FileSearchPanel.search.results.details");
180 MessageNotifyUtil.Notify.info(msg, details);
183 throw new FilterValidationException(
184 NbBundle.getMessage(
this.getClass(),
"FileSearchPanel.search.exception.noFilterSelected.msg"));
186 }
catch (FilterValidationException ex) {
187 NotifyDescriptor d =
new NotifyDescriptor.Message(
188 NbBundle.getMessage(
this.getClass(),
"FileSearchPanel.search.validationErr.msg", ex.getMessage()));
189 DialogDisplayer.getDefault().notify(d);
191 this.setCursor(null);
206 private String getQuery() throws FilterValidationException {
211 for (FileSearchFilter f : this.getEnabledFilters()) {
212 query +=
" and (" + f.getPredicate() +
")";
218 private Collection<FileSearchFilter> getFilters() {
219 Collection<FileSearchFilter> filters =
new ArrayList<FileSearchFilter>();
221 for (FilterArea fa : this.filterAreas) {
222 filters.addAll(fa.getFilters());
228 private Collection<FileSearchFilter> getEnabledFilters() {
229 Collection<FileSearchFilter> enabledFilters =
new ArrayList<FileSearchFilter>();
231 for (FileSearchFilter f : this.getFilters()) {
233 enabledFilters.add(f);
237 return enabledFilters;
240 void addListenerToAll(ActionListener l) {
241 searchButton.addActionListener(l);
242 for (FilterArea fa : this.filterAreas) {
243 for (FileSearchFilter fsf : fa.getFilters()) {
244 fsf.addActionListener(l);
254 @SuppressWarnings(
"unchecked")
256 private
void initComponents() {
258 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
259 this.setLayout(layout);
260 layout.setHorizontalGroup(
261 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
262 .addGap(0, 300, Short.MAX_VALUE)
264 layout.setVerticalGroup(
265 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
266 .addGap(0, 376, Short.MAX_VALUE)