Autopsy  4.4.1
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-2017 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 
51 class DateSearchFilter extends AbstractFileSearchFilter<DateSearchPanel> {
52 
53  private static final String NONE_SELECTED_MESSAGE = NbBundle.getMessage(DateSearchFilter.class, "DateSearchFilter.noneSelectedMsg.text");
54  private static final DateFormat DATE_FORMAT = new SimpleDateFormat("MM/dd/yyyy");
55  private static final String SEPARATOR = "SEPARATOR"; //NON-NLS
56 
57  private static final Set<Case.Events> CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.CURRENT_CASE,
58  Case.Events.DATA_SOURCE_ADDED, Case.Events.DATA_SOURCE_DELETED);
59 
63  DateSearchFilter() {
64  this(new DateSearchPanel(DATE_FORMAT, DateSearchFilter.createTimeZoneList()));
65  }
66 
67  private DateSearchFilter(DateSearchPanel panel) {
68  super(panel);
69  Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, this.new CasePropertyChangeListener());
70  }
71 
72  @Override
73  public boolean isEnabled() {
74  return this.getComponent().getDateCheckBox().isSelected();
75  }
76 
77  @Override
78  public String getPredicate() throws FilterValidationException {
79  String query = "NULL";
80  DateSearchPanel panel = this.getComponent();
81 
82  // first, get the selected timeZone from the dropdown list
83  String tz = this.getComponent().getTimeZoneComboBox().getSelectedItem().toString();
84  String tzID = tz.substring(tz.indexOf(" ") + 1); // 1 index after the space is the ID
85  TimeZone selectedTZ = TimeZone.getTimeZone(tzID); //
86 
87  // convert the date from the selected timezone to get the GMT
88  long fromDate = 0;
89  String startDateValue = panel.getDateFromTextField().getText();
90  Calendar startDate = null;
91  try {
92  DateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
93  sdf.setTimeZone(selectedTZ); // get the time in the selected timezone
94  Date temp = sdf.parse(startDateValue);
95 
96  startDate = Calendar.getInstance(new SimpleTimeZone(0, "GMT")); //NON-NLS
97  startDate.setTime(temp); // convert to GMT
98  } catch (ParseException ex) {
99  // for now, no need to show the error message to the user here
100  }
101  if (!startDateValue.isEmpty()) {
102  if (startDate != null) {
103  fromDate = startDate.getTimeInMillis() / 1000; // divided by 1000 because we want to get the seconds, not miliseconds
104  }
105  }
106 
107  long toDate = 0;
108  String endDateValue = panel.getDateToTextField().getText();
109  Calendar endDate = null;
110  try {
111  DateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
112  sdf.setTimeZone(selectedTZ); // get the time in the selected timezone
113  Date temp2 = sdf.parse(endDateValue);
114 
115  endDate = Calendar.getInstance(new SimpleTimeZone(0, "GMT")); //NON-NLS
116  endDate.setTime(temp2); // convert to GMT
117  endDate.set(Calendar.HOUR, endDate.get(Calendar.HOUR) + 24); // get the next 24 hours
118  } catch (ParseException ex) {
119  // for now, no need to show the error message to the user here
120  }
121  if (!endDateValue.isEmpty()) {
122  if (endDate != null) {
123  toDate = endDate.getTimeInMillis() / 1000; // divided by 1000 because we want to get the seconds, not miliseconds
124  }
125  }
126 
127  // If they put the dates in backwards, help them out.
128  if (fromDate > toDate) {
129  long temp = toDate;
130  toDate = fromDate;
131  fromDate = temp;
132  }
133 
134  final boolean modifiedChecked = panel.getModifiedCheckBox().isSelected();
135  final boolean changedChecked = panel.getChangedCheckBox().isSelected();
136  final boolean accessedChecked = panel.getAccessedCheckBox().isSelected();
137  final boolean createdChecked = panel.getCreatedCheckBox().isSelected();
138 
139  if (modifiedChecked || changedChecked || accessedChecked || createdChecked) {
140 
141  if (modifiedChecked) {
142  query += " OR (mtime BETWEEN " + fromDate + " AND " + toDate + ")"; //NON-NLS
143  }
144 
145  if (changedChecked) {
146  query += " OR (ctime BETWEEN " + fromDate + " AND " + toDate + ")"; //NON-NLS
147  }
148 
149  if (accessedChecked) {
150  query += " OR (atime BETWEEN " + fromDate + " AND " + toDate + ")"; //NON-NLS
151  }
152 
153  if (createdChecked) {
154  query += " OR (crtime BETWEEN " + fromDate + " AND " + toDate + ")"; //NON-NLS
155  }
156 
157  } else {
158  throw new FilterValidationException(NONE_SELECTED_MESSAGE);
159  }
160 
161  return query;
162 
163  }
164 
165  private void updateTimeZoneList() {
166  this.getComponent().setTimeZones(DateSearchFilter.createTimeZoneList());
167  }
168 
169  private static List<String> createTimeZoneList() {
170 
171  List<String> timeZones = new ArrayList<>();
172 
173  try {
174  // get the latest case
175  Case currentCase = Case.getCurrentCase(); // get the most updated case
176 
177  Set<TimeZone> caseTimeZones = currentCase.getTimeZones();
178  Iterator<TimeZone> iterator = caseTimeZones.iterator();
179  while (iterator.hasNext()) {
180  TimeZone zone = iterator.next();
181  int offset = zone.getRawOffset() / 1000;
182  int hour = offset / 3600;
183  int minutes = (offset % 3600) / 60;
184  String item = String.format("(GMT%+d:%02d) %s", hour, minutes, zone.getID()); //NON-NLS
185  timeZones.add(item);
186  }
187 
188  if (caseTimeZones.size() > 0) {
189  timeZones.add(SEPARATOR);
190  }
191 
192  // load and add all timezone
193  String[] ids = SimpleTimeZone.getAvailableIDs();
194  for (String id : ids) {
195  TimeZone zone = TimeZone.getTimeZone(id);
196  int offset = zone.getRawOffset() / 1000;
197  int hour = offset / 3600;
198  int minutes = (offset % 3600) / 60;
199  String item = String.format("(GMT%+d:%02d) %s", hour, minutes, id); //NON-NLS
200  timeZones.add(item);
201  }
202  } catch (IllegalStateException ex) {
203  // No current case.
204  }
205 
206  return timeZones;
207  }
208 
209  @Override
210  public void addActionListener(ActionListener l) {
211  getComponent().addActionListener(l);
212  }
213 
214  @Override
215  public boolean isValid() {
216  return this.getComponent().isValidSearch();
217  }
218 
222  static class ComboBoxRenderer extends JLabel implements ListCellRenderer<String> {
223 
224  JSeparator separator;
225 
226  ComboBoxRenderer() {
227  setOpaque(true);
228  setBorder(new EmptyBorder(1, 1, 1, 1));
229  separator = new JSeparator(JSeparator.HORIZONTAL);
230  }
231 
232  @Override
233  public Component getListCellRendererComponent(JList<? extends String> list, String value, int index, boolean isSelected, boolean cellHasFocus) {
234  String str = (value == null) ? "" : value;
235  if (SEPARATOR.equals(str)) {
236  return separator;
237  }
238  if (isSelected) {
239  setBackground(list.getSelectionBackground());
240  setForeground(list.getSelectionForeground());
241  } else {
242  setBackground(list.getBackground());
243  setForeground(list.getForeground());
244  }
245  setFont(list.getFont());
246  setText(str);
247  return this;
248  }
249  }
250 
251  private class CasePropertyChangeListener implements PropertyChangeListener {
252 
253  @Override
254  public void propertyChange(PropertyChangeEvent evt) {
255  switch (Case.Events.valueOf(evt.getPropertyName())) {
256  case CURRENT_CASE:
257  Object newValue = evt.getNewValue();
258  if (null != newValue) {
262  SwingUtilities.invokeLater(DateSearchFilter.this::updateTimeZoneList);
263  }
264  break;
265  case DATA_SOURCE_ADDED:
266  case DATA_SOURCE_DELETED:
273  try {
275  SwingUtilities.invokeLater(DateSearchFilter.this::updateTimeZoneList);
276  } catch (IllegalStateException notUsed) {
280  }
281  break;
282  }
283  }
284  }
285 }

Copyright © 2012-2016 Basis Technology. Generated on: Fri Sep 29 2017
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.