mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-13 00:16:16 +00:00
Implemented the DoD, tested and commented the code
This commit is contained in:
parent
37e4dce789
commit
477d8c6d72
@ -1,3 +1,7 @@
|
||||
# {0} - month abbreviation
|
||||
# {1} - day of month
|
||||
# {2} - year
|
||||
DiscoveryAttributes.ActivityDateGroupKey.getDisplayNameTemplate=Week of {0} {1}, {2}
|
||||
DiscoveryAttributes.GroupingAttributeType.datasource.displayName=Data Source
|
||||
DiscoveryAttributes.GroupingAttributeType.fileType.displayName=File Type
|
||||
DiscoveryAttributes.GroupingAttributeType.firstDate.displayName=First Activity Date
|
||||
@ -20,11 +24,9 @@ DiscoveryKeyUtils.DataSourceGroupKey.datasourceAndID={0}(ID: {1})
|
||||
# {0} - Data source ID
|
||||
DiscoveryKeyUtils.DataSourceGroupKey.idOnly=Data source (ID: {0})
|
||||
DiscoveryKeyUtils.FileTagGroupKey.noSets=None
|
||||
DiscoveryKeyUtils.FirstActivityDateGroupKey.noDate=No Date Available
|
||||
DiscoveryKeyUtils.HashHitsGroupKey.noHashHits=None
|
||||
DiscoveryKeyUtils.InterestingItemGroupKey.noSets=None
|
||||
DiscoveryKeyUtils.KeywordListGroupKey.noKeywords=None
|
||||
DiscoveryKeyUtils.LastActivityDateGroupKey.noDate=No Date Available
|
||||
DiscoveryKeyUtils.NoGroupingGroupKey.allFiles=All Files
|
||||
DiscoveryKeyUtils.ObjectDetectedGroupKey.noSets=None
|
||||
# {0} - domain
|
||||
|
@ -18,18 +18,21 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.discovery.search;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.Instant;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.temporal.TemporalAdjusters;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.TimeZone;
|
||||
import java.util.logging.Level;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||
import org.sleuthkit.autopsy.discovery.search.SearchData.PageViews;
|
||||
import org.sleuthkit.autopsy.discovery.ui.MonthAbbreviation;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
@ -1134,29 +1137,34 @@ public class DiscoveryKeyUtils {
|
||||
*/
|
||||
static class LastActivityDateGroupKey extends GroupKey {
|
||||
|
||||
private final Long epochDate;
|
||||
private final String dateNameString;
|
||||
private ZonedDateTime currentWeekCutOff;
|
||||
|
||||
/**
|
||||
* Construct a new LastActivityDateGroupKey.
|
||||
*
|
||||
* @param result The Result to create the group key for.
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"DiscoveryKeyUtils.LastActivityDateGroupKey.noDate=No Date Available"})
|
||||
LastActivityDateGroupKey(Result result) {
|
||||
if (result instanceof ResultDomain) {
|
||||
epochDate = ((ResultDomain) result).getActivityEnd();
|
||||
dateNameString = new SimpleDateFormat("yyyy/MM/dd", Locale.getDefault()).format(new Date(TimeUnit.SECONDS.toMillis(epochDate)));
|
||||
ResultDomain domainResult = ((ResultDomain) result);
|
||||
currentWeekCutOff = getCurrentWeekCutOff(domainResult.getActivityEnd(), domainResult);
|
||||
} else {
|
||||
epochDate = Long.MAX_VALUE;
|
||||
dateNameString = Bundle.DiscoveryKeyUtils_LastActivityDateGroupKey_noDate();
|
||||
throw new IllegalArgumentException("Expected a domain result only.");
|
||||
}
|
||||
}
|
||||
|
||||
@NbBundle.Messages({
|
||||
"# {0} - month abbreviation",
|
||||
"# {1} - day of month",
|
||||
"# {2} - year",
|
||||
"DiscoveryAttributes.ActivityDateGroupKey.getDisplayNameTemplate=Week of {0} {1}, {2}"
|
||||
})
|
||||
@Override
|
||||
String getDisplayName() {
|
||||
return getDateNameString();
|
||||
MonthAbbreviation currentCutOffMonth = MonthAbbreviation.fromMonthValue(currentWeekCutOff.getMonthValue());
|
||||
return Bundle.DiscoveryAttributes_ActivityDateGroupKey_getDisplayNameTemplate(
|
||||
currentCutOffMonth.toString(), Integer.toString(currentWeekCutOff.getDayOfMonth()),
|
||||
Integer.toString(currentWeekCutOff.getYear()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1170,53 +1178,40 @@ public class DiscoveryKeyUtils {
|
||||
}
|
||||
|
||||
LastActivityDateGroupKey dateGroupKey = (LastActivityDateGroupKey) otherKey;
|
||||
return getDateNameString().equals(dateGroupKey.getDateNameString());
|
||||
return getDisplayName().equals(dateGroupKey.getDisplayName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(getDateNameString());
|
||||
return Objects.hash(getDisplayName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(GroupKey otherGroupKey) {
|
||||
if (otherGroupKey instanceof LastActivityDateGroupKey) {
|
||||
LastActivityDateGroupKey otherDateGroupKey = (LastActivityDateGroupKey) otherGroupKey;
|
||||
|
||||
// Put the empty list at the end
|
||||
if (this.getEpochDate().equals(Long.MAX_VALUE)) {
|
||||
if (otherDateGroupKey.getEpochDate().equals(Long.MAX_VALUE)) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
} else if (otherDateGroupKey.getEpochDate().equals(Long.MAX_VALUE)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return getDateNameString().compareTo(otherDateGroupKey.getDateNameString());
|
||||
return Long.compare(otherDateGroupKey.currentWeekCutOff.toEpochSecond(), currentWeekCutOff.toEpochSecond());
|
||||
} else {
|
||||
return compareClassNames(otherGroupKey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the date this group is for as a Long.
|
||||
*
|
||||
* @return The date.
|
||||
*/
|
||||
Long getEpochDate() {
|
||||
return epochDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name which identifies this group.
|
||||
*
|
||||
* @return The dateNameString.
|
||||
*/
|
||||
String getDateNameString() {
|
||||
return dateNameString;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next closed Sunday given an epoch time and timezone.
|
||||
* Dates for grouping are managed on a weekly basis. Each Sunday
|
||||
* acts as the boundary and representative for the week.
|
||||
*/
|
||||
private static ZonedDateTime getCurrentWeekCutOff(long epochSeconds, ResultDomain domainResult) {
|
||||
Instant startActivityAsInsant = Instant.ofEpochSecond(epochSeconds);
|
||||
// Determines the timezone using the settings panel or value parsed from the
|
||||
// parent data source
|
||||
TimeZone currentTimeZone = ContentUtils.getTimeZone(domainResult.getDataSource());
|
||||
// Convert to a datetime using epoch and timezone.
|
||||
ZonedDateTime startActivityAsDateTime = ZonedDateTime.ofInstant(startActivityAsInsant, currentTimeZone.toZoneId());
|
||||
// Get the closest Sunday, which is the cut off for the current week.
|
||||
// Use this cut off to perform grouping and comparing.
|
||||
return startActivityAsDateTime.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1224,29 +1219,28 @@ public class DiscoveryKeyUtils {
|
||||
*/
|
||||
static class FirstActivityDateGroupKey extends GroupKey {
|
||||
|
||||
private final Long epochDate;
|
||||
private final String dateNameString;
|
||||
private ZonedDateTime currentWeekCutOff;
|
||||
|
||||
/**
|
||||
* Construct a new FirstActivityDateGroupKey.
|
||||
*
|
||||
* @param result The Result to create the group key for.
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"DiscoveryKeyUtils.FirstActivityDateGroupKey.noDate=No Date Available"})
|
||||
FirstActivityDateGroupKey(Result result) {
|
||||
if (result instanceof ResultDomain) {
|
||||
epochDate = ((ResultDomain) result).getActivityStart();
|
||||
dateNameString = new SimpleDateFormat("yyyy/MM/dd", Locale.getDefault()).format(new Date(TimeUnit.SECONDS.toMillis(epochDate)));
|
||||
ResultDomain domainResult = ((ResultDomain) result);
|
||||
currentWeekCutOff = getCurrentWeekCutOff(domainResult.getActivityStart(), domainResult);
|
||||
} else {
|
||||
epochDate = Long.MAX_VALUE;
|
||||
dateNameString = Bundle.DiscoveryKeyUtils_FirstActivityDateGroupKey_noDate();
|
||||
throw new IllegalArgumentException("Expected a domain result only.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
String getDisplayName() {
|
||||
return getDateNameString();
|
||||
MonthAbbreviation currentCutOffMonth = MonthAbbreviation.fromMonthValue(currentWeekCutOff.getMonthValue());
|
||||
return Bundle.DiscoveryAttributes_ActivityDateGroupKey_getDisplayNameTemplate(
|
||||
currentCutOffMonth.toString(), Integer.toString(currentWeekCutOff.getDayOfMonth()),
|
||||
Integer.toString(currentWeekCutOff.getYear()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1260,53 +1254,23 @@ public class DiscoveryKeyUtils {
|
||||
}
|
||||
|
||||
FirstActivityDateGroupKey dateGroupKey = (FirstActivityDateGroupKey) otherKey;
|
||||
return getDateNameString().equals(dateGroupKey.getDateNameString());
|
||||
return getDisplayName().equals(dateGroupKey.getDisplayName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(getDateNameString());
|
||||
return Objects.hash(getDisplayName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(GroupKey otherGroupKey) {
|
||||
if (otherGroupKey instanceof FirstActivityDateGroupKey) {
|
||||
FirstActivityDateGroupKey otherDateGroupKey = (FirstActivityDateGroupKey) otherGroupKey;
|
||||
|
||||
// Put the empty list at the end
|
||||
if (this.getEpochDate().equals(Long.MAX_VALUE)) {
|
||||
if (otherDateGroupKey.getEpochDate().equals(Long.MAX_VALUE)) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
} else if (otherDateGroupKey.getEpochDate().equals(Long.MAX_VALUE)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return getDateNameString().compareTo(otherDateGroupKey.getDateNameString());
|
||||
return Long.compare(otherDateGroupKey.currentWeekCutOff.toEpochSecond(), currentWeekCutOff.toEpochSecond());
|
||||
} else {
|
||||
return compareClassNames(otherGroupKey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the date this group is for as a Long.
|
||||
*
|
||||
* @return The date.
|
||||
*/
|
||||
Long getEpochDate() {
|
||||
return epochDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name which identifies this group.
|
||||
*
|
||||
* @return The dateNameString.
|
||||
*/
|
||||
String getDateNameString() {
|
||||
return dateNameString;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -24,12 +24,15 @@ import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||
import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.GroupKey;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.datamodel.TimeUtilities;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
@ -245,7 +248,8 @@ public class DomainSearch {
|
||||
private String getDate(BlackboardArtifact artifact) throws TskCoreException {
|
||||
for (BlackboardAttribute attribute : artifact.getAttributes()) {
|
||||
if (attribute.getAttributeType().getTypeName().startsWith("TSK_DATETIME")) {
|
||||
String dateString = attribute.getDisplayString();
|
||||
TimeZone timeZone = ContentUtils.getTimeZone(artifact);
|
||||
String dateString = TimeUtilities.epochToTime(attribute.getValueLong(), timeZone);
|
||||
if (dateString.length() >= 10) {
|
||||
return dateString.substring(0, 10);
|
||||
}
|
||||
|
@ -212,13 +212,14 @@ class DomainSearchCacheLoader extends CacheLoader<SearchKey, Map<GroupKey, List<
|
||||
final StringJoiner whereClause = new StringJoiner(" OR ");
|
||||
final StringJoiner havingClause = new StringJoiner(" AND ");
|
||||
|
||||
String artifactTypeFilter = null;
|
||||
// Capture all types by default.
|
||||
ArtifactTypeFilter artifactTypeFilter = new ArtifactTypeFilter(SearchData.Type.DOMAIN.getArtifactTypes());
|
||||
boolean hasDateTimeFilter = false;
|
||||
|
||||
for (AbstractFilter filter : filters) {
|
||||
if (filter instanceof ArtifactTypeFilter) {
|
||||
artifactTypeFilter = ((ArtifactTypeFilter) filter)
|
||||
.getWhereClause(Arrays.asList(TSK_WEB_ACCOUNT_TYPE));
|
||||
// Replace with user defined types.
|
||||
artifactTypeFilter = ((ArtifactTypeFilter) filter);
|
||||
} else if (!(filter instanceof DataSourceFilter) && !filter.useAlternateFilter()) {
|
||||
if (filter instanceof ArtifactDateRangeFilter) {
|
||||
hasDateTimeFilter = true;
|
||||
@ -240,7 +241,7 @@ class DomainSearchCacheLoader extends CacheLoader<SearchKey, Map<GroupKey, List<
|
||||
havingClause.add("SUM(CASE WHEN " + domainAttributeFilter + " THEN 1 ELSE 0 END) > 0");
|
||||
|
||||
return Pair.of(
|
||||
whereClause.toString() + ((artifactTypeFilter != null) ? " AND (" + artifactTypeFilter + ")" : ""),
|
||||
whereClause.toString() + " AND (" + artifactTypeFilter.getWhereClause(Arrays.asList(TSK_WEB_ACCOUNT_TYPE)) + ")",
|
||||
havingClause.toString()
|
||||
);
|
||||
}
|
||||
|
@ -151,7 +151,7 @@ public class ResultDomain extends Result {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Content getDataSource() throws TskCoreException {
|
||||
public Content getDataSource() {
|
||||
return this.dataSource;
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,13 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
public final class SearchData {
|
||||
|
||||
private final static long BYTES_PER_MB = 1000000;
|
||||
private static final Set<BlackboardArtifact.ARTIFACT_TYPE> DOMAIN_ARTIFACT_TYPES = EnumSet.of(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK, BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE, BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE, BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY, BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY);
|
||||
private static final Set<BlackboardArtifact.ARTIFACT_TYPE> DOMAIN_ARTIFACT_TYPES =
|
||||
EnumSet.of(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK,
|
||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE,
|
||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE,
|
||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD,
|
||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY,
|
||||
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -33,6 +33,7 @@ import org.sleuthkit.datamodel.TagName;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
@ -206,7 +207,7 @@ public class SearchFiltering {
|
||||
*/
|
||||
public static class ArtifactTypeFilter extends AbstractFilter {
|
||||
|
||||
private final List<ARTIFACT_TYPE> types;
|
||||
private final Collection<ARTIFACT_TYPE> types;
|
||||
|
||||
/**
|
||||
* Construct a new ArtifactTypeFilter.
|
||||
@ -214,7 +215,7 @@ public class SearchFiltering {
|
||||
* @param types The list of BlackboardArtifact types to include in
|
||||
* results from.
|
||||
*/
|
||||
public ArtifactTypeFilter(List<ARTIFACT_TYPE> types) {
|
||||
public ArtifactTypeFilter(Collection<ARTIFACT_TYPE> types) {
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
@ -223,8 +224,8 @@ public class SearchFiltering {
|
||||
*
|
||||
* @return The list of artifact types specified by the filter.
|
||||
*/
|
||||
public List<ARTIFACT_TYPE> getTypes() {
|
||||
return Collections.unmodifiableList(types);
|
||||
public Collection<ARTIFACT_TYPE> getTypes() {
|
||||
return Collections.unmodifiableCollection(types);
|
||||
}
|
||||
|
||||
private StringJoiner joinStandardArtifactTypes() {
|
||||
|
@ -72,6 +72,18 @@ MiniTimelineArtifactListPanel.value.noValue=No value available.
|
||||
MiniTimelineDateListPanel.countColumn.name=Count
|
||||
MiniTimelineDateListPanel.dateColumn.name=Date
|
||||
MiniTimelineDateListPanel.value.noValue=No value available.
|
||||
MonthAbbreviation.aprilAbbrev=Apr
|
||||
MonthAbbreviation.augustAbbrev=Aug
|
||||
MonthAbbreviation.decemberAbbrev=Dec
|
||||
MonthAbbreviation.feburaryAbbrev=Feb
|
||||
MonthAbbreviation.januraryAbbrev=Jan
|
||||
MonthAbbreviation.julyAbbrev=Jul
|
||||
MonthAbbreviation.juneAbbrev=Jun
|
||||
MonthAbbreviation.marchAbbrev=Mar
|
||||
MonthAbbreviation.mayAbbrev=May
|
||||
MonthAbbreviation.novemberAbbrev=Nov
|
||||
MonthAbbreviation.octoberAbbrev=Oct
|
||||
MonthAbbreviation.septemberAbbrev=Sep
|
||||
ObjectDetectedFilterPanel.error.text=At least one object type name must be selected.
|
||||
ParentFolderFilterPanel.error.text=At least one parent path must be entered.
|
||||
PastOccurrencesFilterPanel.error.text=At least one value in the past occurrence filter must be selected.
|
||||
|
@ -22,15 +22,16 @@ import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Point;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.time.Instant;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.TimeZone;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.ListCellRenderer;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||
|
||||
/**
|
||||
* Class which displays a preview and details about a domain.
|
||||
@ -39,7 +40,6 @@ class DomainSummaryPanel extends javax.swing.JPanel implements ListCellRenderer<
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Color SELECTION_COLOR = new Color(0, 120, 215);
|
||||
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("MMM dd yyyy", Locale.getDefault());
|
||||
|
||||
/**
|
||||
* Creates new form DomainPanel.
|
||||
@ -149,8 +149,9 @@ class DomainSummaryPanel extends javax.swing.JPanel implements ListCellRenderer<
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList<? extends DomainWrapper> list, DomainWrapper value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
domainNameLabel.setText(value.getResultDomain().getDomain());
|
||||
String startDate = dateFormat.format(new Date(value.getResultDomain().getActivityStart() * 1000));
|
||||
String endDate = dateFormat.format(new Date(value.getResultDomain().getActivityEnd() * 1000));
|
||||
TimeZone timeZone = ContentUtils.getTimeZone(value.getResultDomain().getDataSource());
|
||||
String startDate = formatDate(value.getResultDomain().getActivityStart(), timeZone);
|
||||
String endDate = formatDate(value.getResultDomain().getActivityEnd(), timeZone);
|
||||
activityLabel.setText(Bundle.DomainSummaryPanel_activity_text(startDate, endDate));
|
||||
totalVisitsLabel.setText(Bundle.DomainSummaryPanel_totalPages_text() + value.getResultDomain().getTotalPageViews());
|
||||
pagesLabel.setText(Bundle.DomainSummaryPanel_pages_text() + value.getResultDomain().getPageViewsInLast60Days());
|
||||
@ -165,6 +166,22 @@ class DomainSummaryPanel extends javax.swing.JPanel implements ListCellRenderer<
|
||||
setBackground(isSelected ? SELECTION_COLOR : list.getBackground());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats an epoch time in a given time zone using the following pattern
|
||||
*
|
||||
* MMM dd YYYY
|
||||
*
|
||||
* The pattern below is formatted manually to reuse the MonthAbbreviation utility.
|
||||
*/
|
||||
private String formatDate(long epochSeconds, TimeZone timeZone) {
|
||||
Instant epochSecondsAsInstant = Instant.ofEpochSecond(epochSeconds);
|
||||
ZonedDateTime dateTime = ZonedDateTime.ofInstant(epochSecondsAsInstant, timeZone.toZoneId());
|
||||
MonthAbbreviation currentCutOffMonth = MonthAbbreviation.fromMonthValue(dateTime.getMonthValue());
|
||||
return String.format("%s %02d %04d",
|
||||
currentCutOffMonth.toString(),
|
||||
dateTime.getDayOfMonth(), dateTime.getYear());
|
||||
}
|
||||
|
||||
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
||||
@Override
|
||||
|
80
Core/src/org/sleuthkit/autopsy/discovery/ui/MonthAbbreviation.java
Executable file
80
Core/src/org/sleuthkit/autopsy/discovery/ui/MonthAbbreviation.java
Executable file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Autopsy
|
||||
*
|
||||
* Copyright 2020 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.discovery.ui;
|
||||
|
||||
import org.openide.util.NbBundle;
|
||||
|
||||
/**
|
||||
* Utility for representing month abbreviations
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"MonthAbbreviation.januraryAbbrev=Jan",
|
||||
"MonthAbbreviation.feburaryAbbrev=Feb",
|
||||
"MonthAbbreviation.marchAbbrev=Mar",
|
||||
"MonthAbbreviation.aprilAbbrev=Apr",
|
||||
"MonthAbbreviation.mayAbbrev=May",
|
||||
"MonthAbbreviation.juneAbbrev=Jun",
|
||||
"MonthAbbreviation.julyAbbrev=Jul",
|
||||
"MonthAbbreviation.augustAbbrev=Aug",
|
||||
"MonthAbbreviation.septemberAbbrev=Sep",
|
||||
"MonthAbbreviation.octoberAbbrev=Oct",
|
||||
"MonthAbbreviation.novemberAbbrev=Nov",
|
||||
"MonthAbbreviation.decemberAbbrev=Dec"
|
||||
})
|
||||
public enum MonthAbbreviation {
|
||||
JANURARY(Bundle.MonthAbbreviation_januraryAbbrev()),
|
||||
FEBURARY(Bundle.MonthAbbreviation_feburaryAbbrev()),
|
||||
MARCH(Bundle.MonthAbbreviation_marchAbbrev()),
|
||||
APRIL(Bundle.MonthAbbreviation_aprilAbbrev()),
|
||||
MAY(Bundle.MonthAbbreviation_mayAbbrev()),
|
||||
JUNE(Bundle.MonthAbbreviation_juneAbbrev()),
|
||||
JULY(Bundle.MonthAbbreviation_julyAbbrev()),
|
||||
AUGUST(Bundle.MonthAbbreviation_augustAbbrev()),
|
||||
SEPTEMBER(Bundle.MonthAbbreviation_septemberAbbrev()),
|
||||
OCTOBER(Bundle.MonthAbbreviation_octoberAbbrev()),
|
||||
NOVEMBER(Bundle.MonthAbbreviation_novemberAbbrev()),
|
||||
DECEMBER(Bundle.MonthAbbreviation_decemberAbbrev());
|
||||
|
||||
private final String abbreviation;
|
||||
|
||||
MonthAbbreviation(String abbreviation) {
|
||||
this.abbreviation = abbreviation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.abbreviation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a month value (1-12) to the appropriate abbreviation.
|
||||
*
|
||||
* @param value Month value (1-12).
|
||||
* @return Abbreviation matching the month value, null if not found.
|
||||
*/
|
||||
public static MonthAbbreviation fromMonthValue(int value) {
|
||||
MonthAbbreviation[] months = MonthAbbreviation.values();
|
||||
for(int i = 0; i < months.length; i++) {
|
||||
if (i + 1 == value) {
|
||||
return months[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user