Autopsy  4.15.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
DateSearchFilter.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2011-2018 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 package org.sleuthkit.autopsy.filesearch;
20 
21 import java.awt.Component;
22 import java.awt.event.ActionListener;
23 import java.beans.PropertyChangeEvent;
24 import java.beans.PropertyChangeListener;
25 import java.text.DateFormat;
26 import java.text.ParseException;
27 import java.text.SimpleDateFormat;
28 import java.util.ArrayList;
29 import java.util.Calendar;
30 import java.util.Date;
31 import java.util.EnumSet;
32 import java.util.List;
33 import java.util.Set;
34 import java.util.SimpleTimeZone;
35 import java.util.TimeZone;
36 import javax.swing.JLabel;
37 import javax.swing.JList;
38 import javax.swing.JSeparator;
39 import javax.swing.ListCellRenderer;
40 import javax.swing.SwingUtilities;
41 import javax.swing.border.EmptyBorder;
42 import org.openide.util.NbBundle;
44 import org.openide.util.NbBundle.Messages;
47 
53 class DateSearchFilter extends AbstractFileSearchFilter<DateSearchPanel> {
54 
55  private static final String NONE_SELECTED_MESSAGE = NbBundle.getMessage(DateSearchFilter.class, "DateSearchFilter.noneSelectedMsg.text");
56  private static final DateFormat DATE_FORMAT = new SimpleDateFormat("MM/dd/yyyy");
57  private static final String SEPARATOR = "SEPARATOR"; //NON-NLS
58 
59  private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.CURRENT_CASE,
60  Case.Events.DATA_SOURCE_ADDED, Case.Events.DATA_SOURCE_DELETED);
61 
65  DateSearchFilter() {
66  this(new DateSearchPanel(DATE_FORMAT, DateSearchFilter.createTimeZoneList()));
67  }
68 
69  private DateSearchFilter(DateSearchPanel panel) {
70  super(panel);
71  Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, this.new CasePropertyChangeListener());
72  }
73 
74  @Override
75  public boolean isEnabled() {
76  return this.getComponent().getDateCheckBox().isSelected();
77  }
78 
79  @Override
80  public String getPredicate() throws FilterValidationException {
81  String query = "NULL";
82  DateSearchPanel panel = this.getComponent();
83 
84  // convert the date from the selected timezone to get the GMT
85  long fromDate = 0;
86  String startDateValue = panel.getFromDate();
87  Calendar startDate = getCalendarDate(startDateValue);
88  if (!startDateValue.isEmpty()) {
89  if (startDate != null) {
90  fromDate = startDate.getTimeInMillis() / 1000; // divided by 1000 because we want to get the seconds, not miliseconds
91  }
92  }
93 
94  long toDate = 0;
95  String endDateValue = panel.getToDate();
96  Calendar endDate = getCalendarDate(endDateValue);
97  if (!endDateValue.isEmpty()) {
98  if (endDate != null) {
99  toDate = endDate.getTimeInMillis() / 1000; // divided by 1000 because we want to get the seconds, not miliseconds
100  }
101  }
102 
103  final boolean modifiedChecked = panel.getModifiedCheckBox().isSelected();
104  final boolean changedChecked = panel.getChangedCheckBox().isSelected();
105  final boolean accessedChecked = panel.getAccessedCheckBox().isSelected();
106  final boolean createdChecked = panel.getCreatedCheckBox().isSelected();
107 
108  if (modifiedChecked || changedChecked || accessedChecked || createdChecked) {
109 
110  if (modifiedChecked) {
111  query += " OR (mtime BETWEEN " + fromDate + " AND " + toDate + ")"; //NON-NLS
112  }
113 
114  if (changedChecked) {
115  query += " OR (ctime BETWEEN " + fromDate + " AND " + toDate + ")"; //NON-NLS
116  }
117 
118  if (accessedChecked) {
119  query += " OR (atime BETWEEN " + fromDate + " AND " + toDate + ")"; //NON-NLS
120  }
121 
122  if (createdChecked) {
123  query += " OR (crtime BETWEEN " + fromDate + " AND " + toDate + ")"; //NON-NLS
124  }
125 
126  } else {
127  throw new FilterValidationException(NONE_SELECTED_MESSAGE);
128  }
129 
130  return query;
131 
132  }
133 
134  private void updateTimeZoneList() {
135  this.getComponent().setTimeZones(DateSearchFilter.createTimeZoneList());
136  }
137 
138  private static List<String> createTimeZoneList() {
139 
140  List<String> timeZones = new ArrayList<>();
141 
142  try {
143  // get the latest case
144  Case currentCase = Case.getCurrentCaseThrows(); // get the most updated case
145 
146  Set<TimeZone> caseTimeZones = currentCase.getTimeZones();
147  for (TimeZone timeZone : caseTimeZones) {
148  timeZones.add(TimeZoneUtils.createTimeZoneString(timeZone));
149  }
150 
151  if (caseTimeZones.size() > 0) {
152  timeZones.add(SEPARATOR);
153  }
154 
155  timeZones.addAll(TimeZoneUtils.createTimeZoneList());
156  } catch (NoCurrentCaseException ex) {
157  // No current case.
158  }
159 
160  return timeZones;
161  }
162 
163  private TimeZone getSelectedTimeZone() {
164  String tz = this.getComponent().getTimeZoneComboBox().getSelectedItem().toString();
165  String tzID = tz.substring(tz.indexOf(" ") + 1); // 1 index after the space is the ID
166  TimeZone selectedTZ = TimeZone.getTimeZone(tzID); //
167  return selectedTZ;
168  }
169 
170  private Calendar getCalendarDate(String dateValue) {
171  TimeZone selectedTZ = getSelectedTimeZone();
172  Calendar inputDate = null;
173  try {
174  DateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
175  sdf.setTimeZone(selectedTZ); // get the time in the selected timezone
176  Date temp = sdf.parse(dateValue);
177 
178  inputDate = Calendar.getInstance(new SimpleTimeZone(0, "GMT")); //NON-NLS
179  inputDate.setTime(temp); // convert to GMT
180  } catch (ParseException ex) {
181  // for now, no need to show the error message to the user here
182  }
183  return inputDate;
184  }
185 
186  @Override
187  public void addActionListener(ActionListener l) {
188  getComponent().addDateChangeListener();
189  }
190 
191  @Override
192  @Messages ({
193  "DateSearchFilter.errorMessage.endDateBeforeStartDate=The end date should be after the start date.",
194  "DateSearchFilter.errorMessage.noCheckboxSelected=At least one date type checkbox must be selected."
195  })
196  public boolean isValid() {
197 
198  DateSearchPanel panel = this.getComponent();
199  Calendar startDate = getCalendarDate(panel.getFromDate());
200  Calendar endDate = getCalendarDate(panel.getToDate());
201 
202  if ((startDate != null && startDate.after(endDate)) || (endDate != null && endDate.before(startDate))) {
203  setLastError(Bundle.DateSearchFilter_errorMessage_endDateBeforeStartDate());
204  return false;
205  }
206 
207  if (!panel.isValidSearch()) {
208  setLastError(Bundle.DateSearchFilter_errorMessage_noCheckboxSelected());
209  return false;
210  }
211 
212  return true;
213  }
214 
218  static class ComboBoxRenderer extends JLabel implements ListCellRenderer<String> {
219 
220  JSeparator separator;
221 
222  ComboBoxRenderer() {
223  setOpaque(true);
224  setBorder(new EmptyBorder(1, 1, 1, 1));
225  separator = new JSeparator(JSeparator.HORIZONTAL);
226  }
227 
228  @Override
229  public Component getListCellRendererComponent(JList<? extends String> list, String value, int index, boolean isSelected, boolean cellHasFocus) {
230  String str = (value == null) ? "" : value;
231  if (SEPARATOR.equals(str)) {
232  return separator;
233  }
234  if (isSelected) {
235  setBackground(list.getSelectionBackground());
236  setForeground(list.getSelectionForeground());
237  } else {
238  setBackground(list.getBackground());
239  setForeground(list.getForeground());
240  }
241  setFont(list.getFont());
242  setText(str);
243  return this;
244  }
245  }
246 
247  private class CasePropertyChangeListener implements PropertyChangeListener {
248 
249  @Override
250  public void propertyChange(PropertyChangeEvent evt) {
251  switch (Case.Events.valueOf(evt.getPropertyName())) {
252  case CURRENT_CASE:
253  Object newValue = evt.getNewValue();
254  if (null != newValue) {
258  SwingUtilities.invokeLater(DateSearchFilter.this::updateTimeZoneList);
259  }
260  break;
261  case DATA_SOURCE_ADDED:
262  case DATA_SOURCE_DELETED:
269  try {
271  SwingUtilities.invokeLater(DateSearchFilter.this::updateTimeZoneList);
272  } catch (NoCurrentCaseException notUsed) {
276  }
277  break;
278  }
279  }
280  }
281 }

Copyright © 2012-2020 Basis Technology. Generated on: Mon Jul 6 2020
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.