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 final List<FilterArea> filterAreas =
new ArrayList<>();
64 private static int resultWindowCount = 0;
65 private static final String EMPTY_WHERE_CLAUSE = NbBundle.getMessage(DateSearchFilter.class,
"FileSearchPanel.emptyWhereClause.text");
70 public FileSearchPanel() {
72 customizeComponents();
79 private void customizeComponents() {
81 JLabel label =
new JLabel(NbBundle.getMessage(
this.getClass(),
"FileSearchPanel.custComp.label.text"));
82 label.setAlignmentX(Component.LEFT_ALIGNMENT);
83 label.setBorder(
new EmptyBorder(0, 0, 10, 0));
84 filterPanel.add(label);
87 this.filterAreas.add(
new FilterArea(NbBundle.getMessage(
this.getClass(),
"FileSearchPanel.filterTitle.name"),
new NameSearchFilter()));
89 List<FileSearchFilter> metadataFilters =
new ArrayList<>();
90 metadataFilters.add(
new SizeSearchFilter());
91 metadataFilters.add(
new MimeTypeFilter());
92 metadataFilters.add(
new DateSearchFilter());
93 this.filterAreas.add(
new FilterArea(NbBundle.getMessage(
this.getClass(),
"FileSearchPanel.filterTitle.metadata"), metadataFilters));
95 this.filterAreas.add(
new FilterArea(NbBundle.getMessage(
this.getClass(),
"FileSearchPanel.filterTitle.knownStatus"),
new KnownStatusSearchFilter()));
97 for (FilterArea fa : this.filterAreas) {
98 fa.setMaximumSize(
new Dimension(Integer.MAX_VALUE, fa.getMinimumSize().height));
99 fa.setAlignmentX(Component.LEFT_ALIGNMENT);
103 addListenerToAll(
new ActionListener() {
105 public void actionPerformed(ActionEvent e) {
114 private boolean anyFiltersEnabled() {
115 for (FileSearchFilter filter : this.getFilters()) {
116 if (filter.isEnabled()) {
128 private void search() {
130 this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
132 if (this.anyFiltersEnabled()) {
133 String title = NbBundle.getMessage(this.getClass(),
"FileSearchPanel.search.results.title", ++resultWindowCount);
134 String pathText = NbBundle.getMessage(this.getClass(),
"FileSearchPanel.search.results.pathText");
137 Case currentCase = Case.getCurrentCase();
138 long totalMatches = 0;
139 List<AbstractFile> contentList = null;
141 SleuthkitCase tskDb = currentCase.getSleuthkitCase();
142 contentList = tskDb.findAllFilesWhere(this.getQuery());
144 }
catch (TskCoreException ex) {
145 Logger logger = Logger.getLogger(this.getClass().getName());
146 logger.log(Level.WARNING,
"Error while trying to get the number of matches.", ex);
149 if (contentList == null) {
150 contentList = Collections.<AbstractFile>emptyList();
153 final TopComponent searchResultWin = DataResultTopComponent.createInstance(title, pathText,
154 new TableFilterNode(
new SearchNode(contentList),
true), contentList.size());
156 searchResultWin.requestActive();
163 if (totalMatches > 10000) {
165 String msg = NbBundle.getMessage(this.getClass(),
"FileSearchPanel.search.results.msg", totalMatches);
166 String details = NbBundle.getMessage(this.getClass(),
"FileSearchPanel.search.results.details");
167 MessageNotifyUtil.Notify.info(msg, details);
170 throw new FilterValidationException(
171 NbBundle.getMessage(
this.getClass(),
"FileSearchPanel.search.exception.noFilterSelected.msg"));
173 }
catch (FilterValidationException ex) {
174 NotifyDescriptor d =
new NotifyDescriptor.Message(
175 NbBundle.getMessage(
this.getClass(),
"FileSearchPanel.search.validationErr.msg", ex.getMessage()));
176 DialogDisplayer.getDefault().notify(d);
178 this.setCursor(null);
200 private String getQuery() throws FilterValidationException {
205 for (FileSearchFilter f : this.getEnabledFilters()) {
206 String result = f.getPredicate();
207 if (!result.isEmpty()) {
209 query +=
" AND (" + result +
")";
211 query +=
" (" + result +
")";
217 if (query.isEmpty()) {
218 throw new FilterValidationException(EMPTY_WHERE_CLAUSE);
223 private Collection<FileSearchFilter> getFilters() {
224 Collection<FileSearchFilter> filters =
new ArrayList<>();
226 for (FilterArea fa : this.filterAreas) {
227 filters.addAll(fa.getFilters());
233 private Collection<FileSearchFilter> getEnabledFilters() {
234 Collection<FileSearchFilter> enabledFilters =
new ArrayList<>();
236 for (FileSearchFilter f : this.getFilters()) {
238 enabledFilters.add(f);
242 return enabledFilters;
245 void addListenerToAll(ActionListener l) {
246 searchButton.addActionListener(l);
247 for (FilterArea fa : this.filterAreas) {
248 for (FileSearchFilter fsf : fa.getFilters()) {
249 fsf.addActionListener(l);
259 @SuppressWarnings(
"unchecked")
261 private
void initComponents() {
263 filterPanel =
new javax.swing.JPanel();
264 searchButton =
new javax.swing.JButton();
266 setPreferredSize(
new java.awt.Dimension(300, 300));
268 filterPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10));
269 filterPanel.setPreferredSize(
new java.awt.Dimension(300, 400));
270 filterPanel.setLayout(
new javax.swing.BoxLayout(filterPanel, javax.swing.BoxLayout.Y_AXIS));
272 searchButton.setText(
org.openide.util.NbBundle.getMessage(FileSearchPanel.class,
"FileSearchPanel.searchButton.text"));
274 javax.swing.GroupLayout layout =
new javax.swing.GroupLayout(
this);
275 this.setLayout(layout);
276 layout.setHorizontalGroup(
277 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
278 .addComponent(filterPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
279 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
280 .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
281 .addComponent(searchButton)
284 layout.setVerticalGroup(
285 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
286 .addGroup(layout.createSequentialGroup()
287 .addComponent(filterPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
289 .addComponent(searchButton)
294 private javax.swing.JPanel filterPanel;
295 private javax.swing.JButton searchButton;