Autopsy  4.5.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
FileSearchPanel.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20  /*
21  * FileSearchPanel.java
22  *
23  * Created on Mar 5, 2012, 1:51:50 PM
24  */
25 package org.sleuthkit.autopsy.filesearch;
26 
27 import java.awt.Component;
28 import java.awt.Cursor;
29 import java.awt.Dimension;
30 import java.awt.event.ActionEvent;
31 import java.awt.event.ActionListener;
32 import java.beans.PropertyChangeEvent;
33 import java.beans.PropertyChangeListener;
34 import java.util.ArrayList;
35 import java.util.Collection;
36 import java.util.Collections;
37 import java.util.List;
38 import java.util.logging.Level;
39 import javax.swing.JLabel;
40 import javax.swing.border.EmptyBorder;
41 import org.openide.DialogDisplayer;
42 import org.openide.NotifyDescriptor;
43 import org.openide.util.NbBundle;
44 import org.openide.windows.TopComponent;
51 import org.sleuthkit.datamodel.AbstractFile;
52 import org.sleuthkit.datamodel.SleuthkitCase;
53 import org.sleuthkit.datamodel.TskCoreException;
54 
58 class FileSearchPanel extends javax.swing.JPanel {
59 
60  private final List<FilterArea> filterAreas = new ArrayList<>();
61  private static int resultWindowCount = 0; //keep track of result windows so they get unique names
62  private static final String EMPTY_WHERE_CLAUSE = NbBundle.getMessage(DateSearchFilter.class, "FileSearchPanel.emptyWhereClause.text");
63 
64  enum EVENT {
65  CHECKED
66  }
67 
71  public FileSearchPanel() {
72  initComponents();
73  customizeComponents();
74 
75  }
76 
80  private void customizeComponents() {
81 
82  JLabel label = new JLabel(NbBundle.getMessage(this.getClass(), "FileSearchPanel.custComp.label.text"));
83  label.setAlignmentX(Component.LEFT_ALIGNMENT);
84  label.setBorder(new EmptyBorder(0, 0, 10, 0));
85  filterPanel.add(label);
86 
87  // Create and add filter areas
88  this.filterAreas.add(new FilterArea(NbBundle.getMessage(this.getClass(), "FileSearchPanel.filterTitle.name"), new NameSearchFilter()));
89 
90  List<FileSearchFilter> metadataFilters = new ArrayList<>();
91  metadataFilters.add(new SizeSearchFilter());
92  metadataFilters.add(new MimeTypeFilter());
93  metadataFilters.add(new DateSearchFilter());
94  this.filterAreas.add(new FilterArea(NbBundle.getMessage(this.getClass(), "FileSearchPanel.filterTitle.metadata"), metadataFilters));
95 
96  this.filterAreas.add(new FilterArea(NbBundle.getMessage(this.getClass(), "FileSearchPanel.filterTitle.knownStatus"), new KnownStatusSearchFilter()));
97 
98  this.filterAreas.add(new FilterArea(NbBundle.getMessage(this.getClass(), "HashSearchPanel.md5CheckBox.text"), new HashSearchFilter()));
99 
100  for (FilterArea fa : this.filterAreas) {
101  fa.setMaximumSize(new Dimension(Integer.MAX_VALUE, fa.getMinimumSize().height));
102  fa.setAlignmentX(Component.LEFT_ALIGNMENT);
103  filterPanel.add(fa);
104  }
105 
106  for (FileSearchFilter filter : this.getFilters()) {
107  filter.addPropertyChangeListener(new PropertyChangeListener() {
108  @Override
109  public void propertyChange(PropertyChangeEvent evt) {
110  searchButton.setEnabled(isValidSearch());
111  }
112  });
113  }
114  addListenerToAll(new ActionListener() {
115  @Override
116  public void actionPerformed(ActionEvent e) {
117  search();
118  }
119  });
120  searchButton.setEnabled(isValidSearch());
121  }
122 
126  private boolean isValidSearch() {
127  boolean enabled = false;
128  for (FileSearchFilter filter : this.getFilters()) {
129  if (filter.isEnabled()) {
130  enabled = true;
131  if (!filter.isValid()) {
132  errorLabel.setText(filter.getLastError());
133  return false;
134  }
135  }
136  }
137 
138  errorLabel.setText("");
139  return enabled;
140  }
141 
146  private void search() {
147  // change the cursor to "waiting cursor" for this operation
148  this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
149  try {
150  if (this.isValidSearch()) {
151  String title = NbBundle.getMessage(this.getClass(), "FileSearchPanel.search.results.title", ++resultWindowCount);
152  String pathText = NbBundle.getMessage(this.getClass(), "FileSearchPanel.search.results.pathText");
153 
154  // try to get the number of matches first
155  Case currentCase = Case.getCurrentCase(); // get the most updated case
156  long totalMatches = 0;
157  List<AbstractFile> contentList = null;
158  try {
159  SleuthkitCase tskDb = currentCase.getSleuthkitCase();
160  contentList = tskDb.findAllFilesWhere(this.getQuery());
161 
162  } catch (TskCoreException ex) {
163  Logger logger = Logger.getLogger(this.getClass().getName());
164  logger.log(Level.WARNING, "Error while trying to get the number of matches.", ex); //NON-NLS
165  }
166 
167  if (contentList == null) {
168  contentList = Collections.<AbstractFile>emptyList();
169  }
170 
171  SearchNode sn = new SearchNode(contentList);
172  final TopComponent searchResultWin = DataResultTopComponent.createInstance(title, pathText,
173  new TableFilterNode(sn, true, sn.getName()), contentList.size());
174 
175  searchResultWin.requestActive(); // make it the active top component
176 
182  if (totalMatches > 10000) {
183  // show info
184  String msg = NbBundle.getMessage(this.getClass(), "FileSearchPanel.search.results.msg", totalMatches);
185  String details = NbBundle.getMessage(this.getClass(), "FileSearchPanel.search.results.details");
186  MessageNotifyUtil.Notify.info(msg, details);
187  }
188  } else {
189  throw new FilterValidationException(
190  NbBundle.getMessage(this.getClass(), "FileSearchPanel.search.exception.noFilterSelected.msg"));
191  }
192  } catch (FilterValidationException ex) {
193  NotifyDescriptor d = new NotifyDescriptor.Message(
194  NbBundle.getMessage(this.getClass(), "FileSearchPanel.search.validationErr.msg", ex.getMessage()));
195  DialogDisplayer.getDefault().notify(d);
196  } finally {
197  this.setCursor(null);
198  }
199  }
200 
219  private String getQuery() throws FilterValidationException {
220 
221  //String query = "SELECT " + tempQuery + " FROM tsk_files WHERE ";
222  String query = "";
223  int i = 0;
224  for (FileSearchFilter f : this.getEnabledFilters()) {
225  String result = f.getPredicate();
226  if (!result.isEmpty()) {
227  if (i > 0) {
228  query += " AND (" + result + ")"; //NON-NLS
229  } else {
230  query += " (" + result + ")"; //NON-NLS
231  }
232  ++i;
233  }
234  }
235 
236  if (query.isEmpty()) {
237  throw new FilterValidationException(EMPTY_WHERE_CLAUSE);
238  }
239  return query;
240  }
241 
242  private Collection<FileSearchFilter> getFilters() {
243  Collection<FileSearchFilter> filters = new ArrayList<>();
244 
245  for (FilterArea fa : this.filterAreas) {
246  filters.addAll(fa.getFilters());
247  }
248 
249  return filters;
250  }
251 
252  private Collection<FileSearchFilter> getEnabledFilters() {
253  Collection<FileSearchFilter> enabledFilters = new ArrayList<>();
254 
255  for (FileSearchFilter f : this.getFilters()) {
256  if (f.isEnabled()) {
257  enabledFilters.add(f);
258  }
259  }
260 
261  return enabledFilters;
262  }
263 
264  void addListenerToAll(ActionListener l) {
265  searchButton.addActionListener(l);
266  for (FilterArea fa : this.filterAreas) {
267  for (FileSearchFilter fsf : fa.getFilters()) {
268  fsf.addActionListener(l);
269  }
270  }
271  }
272 
278  @SuppressWarnings("unchecked")
279  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
280  private void initComponents() {
281 
282  filterPanel = new javax.swing.JPanel();
283  searchButton = new javax.swing.JButton();
284  errorLabel = new javax.swing.JLabel();
285 
286  setPreferredSize(new java.awt.Dimension(300, 300));
287 
288  filterPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10));
289  filterPanel.setPreferredSize(new java.awt.Dimension(300, 400));
290  filterPanel.setLayout(new javax.swing.BoxLayout(filterPanel, javax.swing.BoxLayout.Y_AXIS));
291 
292  searchButton.setText(org.openide.util.NbBundle.getMessage(FileSearchPanel.class, "FileSearchPanel.searchButton.text")); // NOI18N
293 
294  errorLabel.setForeground(new java.awt.Color(255, 51, 51));
295  errorLabel.setText(org.openide.util.NbBundle.getMessage(FileSearchPanel.class, "FileSearchPanel.errorLabel.text")); // NOI18N
296 
297  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
298  this.setLayout(layout);
299  layout.setHorizontalGroup(
300  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
301  .addComponent(filterPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
302  .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
303  .addContainerGap()
304  .addComponent(errorLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
305  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
306  .addComponent(searchButton)
307  .addContainerGap())
308  );
309  layout.setVerticalGroup(
310  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
311  .addGroup(layout.createSequentialGroup()
312  .addComponent(filterPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 266, Short.MAX_VALUE)
313  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
314  .addComponent(searchButton)
315  .addComponent(errorLabel))
316  .addContainerGap())
317  );
318  }// </editor-fold>//GEN-END:initComponents
319 
320  // Variables declaration - do not modify//GEN-BEGIN:variables
321  private javax.swing.JLabel errorLabel;
322  private javax.swing.JPanel filterPanel;
323  private javax.swing.JButton searchButton;
324  // End of variables declaration//GEN-END:variables
325 }

Copyright © 2012-2016 Basis Technology. Generated on: Tue Feb 20 2018
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.