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.List;
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;
53 class DateSearchFilter
extends AbstractFileSearchFilter<DateSearchPanel> {
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";
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);
66 this(
new DateSearchPanel(DATE_FORMAT, DateSearchFilter.createTimeZoneList()));
69 private DateSearchFilter(DateSearchPanel panel) {
71 Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, this.
new CasePropertyChangeListener());
75 public boolean isEnabled() {
76 return this.getComponent().getDateCheckBox().isSelected();
80 public String getPredicate() throws FilterValidationException {
81 String query =
"NULL";
82 DateSearchPanel panel = this.getComponent();
86 String startDateValue = panel.getFromDate();
87 Calendar startDate = getCalendarDate(startDateValue);
88 if (!startDateValue.isEmpty()) {
89 if (startDate != null) {
90 fromDate = startDate.getTimeInMillis() / 1000;
95 String endDateValue = panel.getToDate();
96 Calendar endDate = getCalendarDate(endDateValue);
97 if (!endDateValue.isEmpty()) {
98 if (endDate != null) {
99 toDate = endDate.getTimeInMillis() / 1000;
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();
108 if (modifiedChecked || changedChecked || accessedChecked || createdChecked) {
110 if (modifiedChecked) {
111 query +=
" OR (mtime BETWEEN " + fromDate +
" AND " + toDate +
")";
114 if (changedChecked) {
115 query +=
" OR (ctime BETWEEN " + fromDate +
" AND " + toDate +
")";
118 if (accessedChecked) {
119 query +=
" OR (atime BETWEEN " + fromDate +
" AND " + toDate +
")";
122 if (createdChecked) {
123 query +=
" OR (crtime BETWEEN " + fromDate +
" AND " + toDate +
")";
127 throw new FilterValidationException(NONE_SELECTED_MESSAGE);
134 private void updateTimeZoneList() {
135 this.getComponent().setTimeZones(DateSearchFilter.createTimeZoneList());
138 private static List<String> createTimeZoneList() {
140 List<String> timeZones =
new ArrayList<>();
144 Case currentCase = Case.getCurrentCaseThrows();
146 Set<TimeZone> caseTimeZones = currentCase.getTimeZones();
147 for (TimeZone timeZone : caseTimeZones) {
148 timeZones.add(TimeZoneUtils.createTimeZoneString(timeZone));
151 if (caseTimeZones.size() > 0) {
152 timeZones.add(SEPARATOR);
155 timeZones.addAll(TimeZoneUtils.createTimeZoneList());
156 }
catch (NoCurrentCaseException ex) {
163 private TimeZone getSelectedTimeZone() {
164 String tz = this.getComponent().getTimeZoneComboBox().getSelectedItem().toString();
165 String tzID = tz.substring(tz.indexOf(
" ") + 1);
166 TimeZone selectedTZ = TimeZone.getTimeZone(tzID);
170 private Calendar getCalendarDate(String dateValue) {
171 TimeZone selectedTZ = getSelectedTimeZone();
172 Calendar inputDate = null;
174 DateFormat sdf =
new SimpleDateFormat(
"MM/dd/yyyy");
175 sdf.setTimeZone(selectedTZ);
176 Date temp = sdf.parse(dateValue);
178 inputDate = Calendar.getInstance(
new SimpleTimeZone(0,
"GMT"));
179 inputDate.setTime(temp);
180 }
catch (ParseException ex) {
187 public void addActionListener(ActionListener l) {
188 getComponent().addDateChangeListener();
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."
196 public boolean isValid() {
198 DateSearchPanel panel = this.getComponent();
199 Calendar startDate = getCalendarDate(panel.getFromDate());
200 Calendar endDate = getCalendarDate(panel.getToDate());
202 if ((startDate != null && startDate.after(endDate)) || (endDate != null && endDate.before(startDate))) {
203 setLastError(Bundle.DateSearchFilter_errorMessage_endDateBeforeStartDate());
207 if (!panel.isValidSearch()) {
208 setLastError(Bundle.DateSearchFilter_errorMessage_noCheckboxSelected());
218 static class ComboBoxRenderer
extends JLabel implements ListCellRenderer<String> {
220 JSeparator separator;
224 setBorder(
new EmptyBorder(1, 1, 1, 1));
225 separator =
new JSeparator(JSeparator.HORIZONTAL);
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)) {
235 setBackground(list.getSelectionBackground());
236 setForeground(list.getSelectionForeground());
238 setBackground(list.getBackground());
239 setForeground(list.getForeground());
241 setFont(list.getFont());
251 switch (
Case.
Events.valueOf(evt.getPropertyName())) {
253 Object newValue = evt.getNewValue();
254 if (null != newValue) {
258 SwingUtilities.invokeLater(DateSearchFilter.this::updateTimeZoneList);
261 case DATA_SOURCE_ADDED:
262 case DATA_SOURCE_DELETED:
271 SwingUtilities.invokeLater(DateSearchFilter.this::updateTimeZoneList);
void propertyChange(PropertyChangeEvent evt)
static Case getCurrentCaseThrows()