19 package org.sleuthkit.autopsy.datasourcesummary.ui;
 
   21 import java.awt.Color;
 
   22 import java.text.DateFormat;
 
   23 import java.text.SimpleDateFormat;
 
   24 import java.util.ArrayList;
 
   25 import java.util.Arrays;
 
   26 import java.util.Date;
 
   27 import java.util.List;
 
   28 import java.util.Locale;
 
   29 import java.util.logging.Level;
 
   30 import org.apache.commons.collections.CollectionUtils;
 
   31 import org.joda.time.DateTime;
 
   32 import org.joda.time.Interval;
 
   33 import org.openide.util.NbBundle.Messages;
 
   34 import org.openide.util.actions.CallableSystemAction;
 
   62     "TimelinePanel_earliestLabel_title=Earliest",
 
   63     "TimelinePanel_latestLabel_title=Latest",
 
   64     "TimlinePanel_last30DaysChart_title=Last 30 Days",
 
   65     "TimlinePanel_last30DaysChart_fileEvts_title=File Events",
 
   66     "TimlinePanel_last30DaysChart_artifactEvts_title=Result Events",})
 
   70     private static final long serialVersionUID = 1L;
 
   71     private static final DateFormat EARLIEST_LATEST_FORMAT = getUtcFormat(
"MMM d, yyyy");
 
   72     private static final DateFormat CHART_FORMAT = getUtcFormat(
"MMM d, yyyy");
 
   73     private static final int MOST_RECENT_DAYS_COUNT = 30;
 
   82         return new SimpleDateFormat(formatString, Locale.getDefault());
 
   93     private final List<LoadableComponent<?>> loadableComponents = Arrays.asList(earliestLabel, latestLabel, last30DaysChart);
 
  109         dataFetchComponents = Arrays.asList(
 
  111                         (dataSource) -> timelineData.
getData(dataSource, MOST_RECENT_DAYS_COUNT),
 
  112                         (result) -> handleResult(result))
 
  127     private static String 
formatDate(Date date, DateFormat formatter) {
 
  128         return date == null ? null : formatter.format(date);
 
  131     private static final Color FILE_EVT_COLOR = 
new Color(228, 22, 28);
 
  132     private static final Color ARTIFACT_EVT_COLOR = 
new Color(21, 227, 100);
 
  141     private List<BarChartSeries> 
parseChartData(List<DailyActivityAmount> recentDaysActivity) {
 
  143         if (CollectionUtils.isEmpty(recentDaysActivity)) {
 
  148         List<BarChartItem> fileEvtCounts = 
new ArrayList<>();
 
  149         List<BarChartItem> artifactEvtCounts = 
new ArrayList<>();
 
  151         for (
int i = 0; i < recentDaysActivity.size(); i++) {
 
  156             String formattedDate = (i == 0 || i == recentDaysActivity.size() - 1)
 
  157                     ? formatDate(curItem.
getDay(), CHART_FORMAT) : 
"";
 
  161             artifactEvtCounts.add(
new BarChartItem(thisKey, artifactAmt));
 
  164         return Arrays.asList(
 
  165                 new BarChartSeries(Bundle.TimlinePanel_last30DaysChart_fileEvts_title(), FILE_EVT_COLOR, fileEvtCounts),
 
  166                 new BarChartSeries(Bundle.TimlinePanel_last30DaysChart_artifactEvts_title(), ARTIFACT_EVT_COLOR, artifactEvtCounts));
 
  169     private final Object timelineBtnLock = 
new Object();
 
  189             synchronized (this.timelineBtnLock) {
 
  190                 this.curTimelineData = result.
getData();
 
  191                 this.viewInTimelineBtn.setEnabled(
true);
 
  194             synchronized (this.timelineBtnLock) {
 
  195                 this.viewInTimelineBtn.setEnabled(
false);
 
  204         DataSource dataSource = null;
 
  209         synchronized (this.timelineBtnLock) {
 
  210             if (curTimelineData == null) {
 
  219                 if (maxDate != null) {
 
  220                     maxDate = 
new Date(maxDate.getTime() + 1000 * 60 * 60 * 24);
 
  225         openFilteredChart(dataSource, minDate, maxDate);
 
  237         if (openTimelineAction == null) {
 
  238             logger.log(Level.WARNING, 
"No OpenTimelineAction provided by CallableSystemAction; taking no redirect action.");
 
  244         Interval timeSpan = null;
 
  249             if (dataSource != null) {
 
  253             if (minDate != null && maxDate != null) {
 
  254                 timeSpan = 
new Interval(
new DateTime(minDate), 
new DateTime(maxDate));
 
  257             logger.log(Level.WARNING, 
"Unable to view time range in Timeline view", ex);
 
  262         } 
catch (TskCoreException ex) {
 
  263             logger.log(Level.WARNING, 
"An unexpected exception occurred while opening the timeline.", ex);
 
  269         fetchInformation(dataFetchComponents, dataSource);
 
  274         onNewDataSource(dataFetchComponents, loadableComponents, dataSource);
 
  288     @SuppressWarnings(
"unchecked")
 
  290     private 
void initComponents() {
 
  292         javax.swing.JScrollPane mainScrollPane = 
new javax.swing.JScrollPane();
 
  293         javax.swing.JPanel mainContentPanel = 
new javax.swing.JPanel();
 
  294         javax.swing.JPanel ingestRunningPanel = ingestRunningLabel;
 
  295         javax.swing.JLabel activityRangeLabel = 
new javax.swing.JLabel();
 
  296         javax.swing.Box.Filler filler1 = 
new javax.swing.Box.Filler(
new java.awt.Dimension(0, 2), 
new java.awt.Dimension(0, 2), 
new java.awt.Dimension(0, 2));
 
  297         javax.swing.JPanel earliestLabelPanel = earliestLabel;
 
  298         javax.swing.JPanel latestLabelPanel = latestLabel;
 
  299         javax.swing.Box.Filler filler2 = 
new javax.swing.Box.Filler(
new java.awt.Dimension(0, 20), 
new java.awt.Dimension(0, 20), 
new java.awt.Dimension(0, 20));
 
  300         javax.swing.JPanel last30DaysPanel = last30DaysChart;
 
  301         viewInTimelineBtn = 
new javax.swing.JButton();
 
  302         javax.swing.Box.Filler filler5 = 
new javax.swing.Box.Filler(
new java.awt.Dimension(0, 0), 
new java.awt.Dimension(0, 0), 
new java.awt.Dimension(0, 32767));
 
  304         mainContentPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10));
 
  305         mainContentPanel.setLayout(
new javax.swing.BoxLayout(mainContentPanel, javax.swing.BoxLayout.PAGE_AXIS));
 
  307         ingestRunningPanel.setAlignmentX(0.0F);
 
  308         ingestRunningPanel.setMaximumSize(
new java.awt.Dimension(32767, 25));
 
  309         ingestRunningPanel.setMinimumSize(
new java.awt.Dimension(10, 25));
 
  310         ingestRunningPanel.setPreferredSize(
new java.awt.Dimension(10, 25));
 
  311         mainContentPanel.add(ingestRunningPanel);
 
  313         activityRangeLabel.setFont(
new java.awt.Font(
"Segoe UI", 1, 12)); 
 
  314         org.openide.awt.Mnemonics.setLocalizedText(activityRangeLabel, 
org.openide.util.NbBundle.getMessage(
TimelinePanel.class, 
"TimelinePanel.activityRangeLabel.text")); 
 
  315         mainContentPanel.add(activityRangeLabel);
 
  316         activityRangeLabel.getAccessibleContext().setAccessibleName(
org.openide.util.NbBundle.getMessage(
TimelinePanel.class, 
"PastCasesPanel.notableFileLabel.text")); 
 
  318         filler1.setAlignmentX(0.0F);
 
  319         mainContentPanel.add(filler1);
 
  321         earliestLabelPanel.setAlignmentX(0.0F);
 
  322         earliestLabelPanel.setMaximumSize(
new java.awt.Dimension(32767, 20));
 
  323         earliestLabelPanel.setMinimumSize(
new java.awt.Dimension(100, 20));
 
  324         earliestLabelPanel.setPreferredSize(
new java.awt.Dimension(100, 20));
 
  325         mainContentPanel.add(earliestLabelPanel);
 
  327         latestLabelPanel.setAlignmentX(0.0F);
 
  328         latestLabelPanel.setMaximumSize(
new java.awt.Dimension(32767, 20));
 
  329         latestLabelPanel.setMinimumSize(
new java.awt.Dimension(100, 20));
 
  330         latestLabelPanel.setPreferredSize(
new java.awt.Dimension(100, 20));
 
  331         mainContentPanel.add(latestLabelPanel);
 
  333         filler2.setAlignmentX(0.0F);
 
  334         mainContentPanel.add(filler2);
 
  336         last30DaysPanel.setAlignmentX(0.0F);
 
  337         last30DaysPanel.setMaximumSize(
new java.awt.Dimension(600, 300));
 
  338         last30DaysPanel.setMinimumSize(
new java.awt.Dimension(600, 300));
 
  339         last30DaysPanel.setPreferredSize(
new java.awt.Dimension(600, 300));
 
  340         last30DaysPanel.setVerifyInputWhenFocusTarget(
false);
 
  341         mainContentPanel.add(last30DaysPanel);
 
  343         org.openide.awt.Mnemonics.setLocalizedText(viewInTimelineBtn, 
org.openide.util.NbBundle.getMessage(
TimelinePanel.class, 
"TimelinePanel.viewInTimelineBtn.text")); 
 
  344         viewInTimelineBtn.setEnabled(
false);
 
  345         viewInTimelineBtn.addActionListener(
new java.awt.event.ActionListener() {
 
  346             public void actionPerformed(java.awt.event.ActionEvent evt) {
 
  347                 viewInTimelineBtnActionPerformed(evt);
 
  350         mainContentPanel.add(viewInTimelineBtn);
 
  352         filler5.setAlignmentX(0.0F);
 
  353         mainContentPanel.add(filler5);
 
  355         mainScrollPane.setViewportView(mainContentPanel);
 
  357         javax.swing.GroupLayout layout = 
new javax.swing.GroupLayout(
this);
 
  358         this.setLayout(layout);
 
  359         layout.setHorizontalGroup(
 
  360             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  361             .addComponent(mainScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
 
  363         layout.setVerticalGroup(
 
  364             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 
  365             .addComponent(mainScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
 
static DateFormat getUtcFormat(String formatString)
 
static< I, O > DataFetchResult< O > getSubResult(DataFetchResult< I > inputResult, Function< I, O > getSubResult)
 
javax.swing.JButton viewInTimelineBtn
 
ResultType getResultType()
 
synchronized void showTimeline(AbstractFile file, BlackboardArtifact artifact, Interval timeSpan)
 
final List< DataFetchComponents< DataSource,?> > dataFetchComponents
 
DataSource getDataSource()
 
long getArtifactActivityCount()
 
void showDataFetchResult(DataFetchResult< T > result, String errorMessage, String noResultsMessage)
 
void handleResult(DataFetchResult< TimelineSummaryData > result)
 
static String formatDate(Date date, DateFormat formatter)
 
void onNewDataSource(DataSource dataSource)
 
void viewInTimelineBtnActionPerformed(java.awt.event.ActionEvent evt)
 
RootFilterState getDataSourceFilterState(DataSource dataSource)
 
List< BarChartSeries > parseChartData(List< DailyActivityAmount > recentDaysActivity)
 
List< DailyActivityAmount > getMostRecentDaysActivity()
 
void openFilteredChart(DataSource dataSource, Date minDate, Date maxDate)
 
void fetchInformation(DataSource dataSource)
 
synchronized void pushFilters(RootFilterState filter)
 
static TimelineDataSourceUtils getInstance()
 
TimelineSummaryData getData(DataSource dataSource, int recentDaysNum)
 
synchronized static Logger getLogger(String name)
 
static TimeLineController getController()
 
long getFileActivityCount()
 
TimelinePanel(TimelineSummary timelineData)