19 package org.sleuthkit.autopsy.filesearch;
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;
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;
51 class DateSearchFilter
extends AbstractFileSearchFilter<DateSearchPanel> {
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";
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);
64 this(
new DateSearchPanel(DATE_FORMAT, DateSearchFilter.createTimeZoneList()));
67 private DateSearchFilter(DateSearchPanel panel) {
69 Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, this.
new CasePropertyChangeListener());
73 public boolean isEnabled() {
74 return this.getComponent().getDateCheckBox().isSelected();
78 public String getPredicate() throws FilterValidationException {
79 String query =
"NULL";
80 DateSearchPanel panel = this.getComponent();
83 String tz = this.getComponent().getTimeZoneComboBox().getSelectedItem().toString();
84 String tzID = tz.substring(tz.indexOf(
" ") + 1);
85 TimeZone selectedTZ = TimeZone.getTimeZone(tzID);
89 String startDateValue = panel.getDateFromTextField().getText();
90 Calendar startDate = null;
92 DateFormat sdf =
new SimpleDateFormat(
"MM/dd/yyyy");
93 sdf.setTimeZone(selectedTZ);
94 Date temp = sdf.parse(startDateValue);
96 startDate = Calendar.getInstance(
new SimpleTimeZone(0,
"GMT"));
97 startDate.setTime(temp);
98 }
catch (ParseException ex) {
101 if (!startDateValue.isEmpty()) {
102 if (startDate != null) {
103 fromDate = startDate.getTimeInMillis() / 1000;
108 String endDateValue = panel.getDateToTextField().getText();
109 Calendar endDate = null;
111 DateFormat sdf =
new SimpleDateFormat(
"MM/dd/yyyy");
112 sdf.setTimeZone(selectedTZ);
113 Date temp2 = sdf.parse(endDateValue);
115 endDate = Calendar.getInstance(
new SimpleTimeZone(0,
"GMT"));
116 endDate.setTime(temp2);
117 endDate.set(Calendar.HOUR, endDate.get(Calendar.HOUR) + 24);
118 }
catch (ParseException ex) {
121 if (!endDateValue.isEmpty()) {
122 if (endDate != null) {
123 toDate = endDate.getTimeInMillis() / 1000;
128 if (fromDate > toDate) {
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();
139 if (modifiedChecked || changedChecked || accessedChecked || createdChecked) {
141 if (modifiedChecked) {
142 query +=
" OR (mtime BETWEEN " + fromDate +
" AND " + toDate +
")";
145 if (changedChecked) {
146 query +=
" OR (ctime BETWEEN " + fromDate +
" AND " + toDate +
")";
149 if (accessedChecked) {
150 query +=
" OR (atime BETWEEN " + fromDate +
" AND " + toDate +
")";
153 if (createdChecked) {
154 query +=
" OR (crtime BETWEEN " + fromDate +
" AND " + toDate +
")";
158 throw new FilterValidationException(NONE_SELECTED_MESSAGE);
165 private void updateTimeZoneList() {
166 this.getComponent().setTimeZones(DateSearchFilter.createTimeZoneList());
169 private static List<String> createTimeZoneList() {
171 List<String> timeZones =
new ArrayList<>();
175 Case currentCase = Case.getCurrentCase();
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());
188 if (caseTimeZones.size() > 0) {
189 timeZones.add(SEPARATOR);
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);
202 }
catch (IllegalStateException ex) {
210 public void addActionListener(ActionListener l) {
211 getComponent().addActionListener(l);
215 public boolean isValid() {
216 return this.getComponent().isValidSearch();
222 static class ComboBoxRenderer
extends JLabel implements ListCellRenderer<String> {
224 JSeparator separator;
228 setBorder(
new EmptyBorder(1, 1, 1, 1));
229 separator =
new JSeparator(JSeparator.HORIZONTAL);
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)) {
239 setBackground(list.getSelectionBackground());
240 setForeground(list.getSelectionForeground());
242 setBackground(list.getBackground());
243 setForeground(list.getForeground());
245 setFont(list.getFont());
255 switch (
Case.
Events.valueOf(evt.getPropertyName())) {
257 Object newValue = evt.getNewValue();
258 if (null != newValue) {
262 SwingUtilities.invokeLater(DateSearchFilter.this::updateTimeZoneList);
265 case DATA_SOURCE_ADDED:
266 case DATA_SOURCE_DELETED:
275 SwingUtilities.invokeLater(DateSearchFilter.this::updateTimeZoneList);
276 }
catch (IllegalStateException notUsed) {
void propertyChange(PropertyChangeEvent evt)
static Case getCurrentCase()