Autopsy  4.7.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.Iterator;
33 import java.util.List;
34 import java.util.Set;
35 import java.util.SimpleTimeZone;
36 import java.util.TimeZone;
37 import javax.swing.JLabel;
38 import javax.swing.JList;
39 import javax.swing.JSeparator;
40 import javax.swing.ListCellRenderer;
41 import javax.swing.SwingUtilities;
42 import javax.swing.border.EmptyBorder;
43 import org.openide.util.NbBundle;
45 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  Iterator<TimeZone> iterator = caseTimeZones.iterator();
148  while (iterator.hasNext()) {
149  TimeZone zone = iterator.next();
150  int offset = zone.getRawOffset() / 1000;
151  int hour = offset / 3600;
152  int minutes = (offset % 3600) / 60;
153  String item = String.format("(GMT%+d:%02d) %s", hour, minutes, zone.getID()); //NON-NLS
154  timeZones.add(item);
155  }
156 
157  if (caseTimeZones.size() > 0) {
158  timeZones.add(SEPARATOR);
159  }
160 
161  // load and add all timezone
162  String[] ids = SimpleTimeZone.getAvailableIDs();
163  for (String id : ids) {
164  TimeZone zone = TimeZone.getTimeZone(id);
165  int offset = zone.getRawOffset() / 1000;
166  int hour = offset / 3600;
167  int minutes = (offset % 3600) / 60;
168  String item = String.format("(GMT%+d:%02d) %s", hour, minutes, id); //NON-NLS
169  timeZones.add(item);
170  }
171  } catch (NoCurrentCaseException ex) {
172  // No current case.
173  }
174 
175  return timeZones;
176  }
177 
178  private TimeZone getSelectedTimeZone() {
179  String tz = this.getComponent().getTimeZoneComboBox().getSelectedItem().toString();
180  String tzID = tz.substring(tz.indexOf(" ") + 1); // 1 index after the space is the ID
181  TimeZone selectedTZ = TimeZone.getTimeZone(tzID); //
182  return selectedTZ;
183  }
184 
185  private Calendar getCalendarDate(String dateValue) {
186  TimeZone selectedTZ = getSelectedTimeZone();
187  Calendar inputDate = null;
188  try {
189  DateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
190  sdf.setTimeZone(selectedTZ); // get the time in the selected timezone
191  Date temp = sdf.parse(dateValue);
192 
193  inputDate = Calendar.getInstance(new SimpleTimeZone(0, "GMT")); //NON-NLS
194  inputDate.setTime(temp); // convert to GMT
195  } catch (ParseException ex) {
196  // for now, no need to show the error message to the user here
197  }
198  return inputDate;
199  }
200 
201  @Override
202  public void addActionListener(ActionListener l) {
203  getComponent().addDateChangeListener();
204  }
205 
206  @Override
207  @Messages ({
208  "DateSearchFilter.errorMessage.endDateBeforeStartDate=The end date should be after the start date.",
209  "DateSearchFilter.errorMessage.noCheckboxSelected=At least one date type checkbox must be selected."
210  })
211  public boolean isValid() {
212 
213  DateSearchPanel panel = this.getComponent();
214  Calendar startDate = getCalendarDate(panel.getFromDate());
215  Calendar endDate = getCalendarDate(panel.getToDate());
216 
217  if ((startDate != null && startDate.after(endDate)) || (endDate != null && endDate.before(startDate))) {
218  setLastError(Bundle.DateSearchFilter_errorMessage_endDateBeforeStartDate());
219  return false;
220  }
221 
222  if (!panel.isValidSearch()) {
223  setLastError(Bundle.DateSearchFilter_errorMessage_noCheckboxSelected());
224  return false;
225  }
226 
227  return true;
228  }
229 
233  static class ComboBoxRenderer extends JLabel implements ListCellRenderer<String> {
234 
235  JSeparator separator;
236 
237  ComboBoxRenderer() {
238  setOpaque(true);
239  setBorder(new EmptyBorder(1, 1, 1, 1));
240  separator = new JSeparator(JSeparator.HORIZONTAL);
241  }
242 
243  @Override
244  public Component getListCellRendererComponent(JList<? extends String> list, String value, int index, boolean isSelected, boolean cellHasFocus) {
245  String str = (value == null) ? "" : value;
246  if (SEPARATOR.equals(str)) {
247  return separator;
248  }
249  if (isSelected) {
250  setBackground(list.getSelectionBackground());
251  setForeground(list.getSelectionForeground());
252  } else {
253  setBackground(list.getBackground());
254  setForeground(list.getForeground());
255  }
256  setFont(list.getFont());
257  setText(str);
258  return this;
259  }
260  }
261 
262  private class CasePropertyChangeListener implements PropertyChangeListener {
263 
264  @Override
265  public void propertyChange(PropertyChangeEvent evt) {
266  switch (Case.Events.valueOf(evt.getPropertyName())) {
267  case CURRENT_CASE:
268  Object newValue = evt.getNewValue();
269  if (null != newValue) {
273  SwingUtilities.invokeLater(DateSearchFilter.this::updateTimeZoneList);
274  }
275  break;
276  case DATA_SOURCE_ADDED:
277  case DATA_SOURCE_DELETED:
284  try {
286  SwingUtilities.invokeLater(DateSearchFilter.this::updateTimeZoneList);
287  } catch (NoCurrentCaseException notUsed) {
291  }
292  break;
293  }
294  }
295  }
296 }

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