mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 16:06:15 +00:00
Merge branch 'develop' of https://github.com/sleuthkit/autopsy into 1205-download-source
This commit is contained in:
commit
90177a7fb6
@ -6,3 +6,4 @@ DataContentViewerOtherCases.showCommonalityMenuItem.text=Show Frequency
|
|||||||
DataContentViewerOtherCases.earliestCaseDate.text=Earliest Case Date
|
DataContentViewerOtherCases.earliestCaseDate.text=Earliest Case Date
|
||||||
DataContentViewerOtherCases.earliestCaseLabel.toolTipText=
|
DataContentViewerOtherCases.earliestCaseLabel.toolTipText=
|
||||||
DataContentViewerOtherCases.earliestCaseLabel.text=Central Repository Starting Date:
|
DataContentViewerOtherCases.earliestCaseLabel.text=Central Repository Starting Date:
|
||||||
|
DataContentViewerOtherCases.foundInLabel.text=
|
||||||
|
@ -73,7 +73,7 @@
|
|||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
<DimensionLayout dim="1">
|
<DimensionLayout dim="1">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Component id="otherCasesPanel" pref="58" max="32767" attributes="0"/>
|
<Component id="otherCasesPanel" pref="53" max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
</Layout>
|
</Layout>
|
||||||
@ -96,10 +96,10 @@
|
|||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
<DimensionLayout dim="1">
|
<DimensionLayout dim="1">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<EmptySpace min="0" pref="483" max="32767" attributes="0"/>
|
<EmptySpace min="0" pref="61" max="32767" attributes="0"/>
|
||||||
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<Component id="tableContainerPanel" pref="58" max="32767" attributes="0"/>
|
<Component id="tableContainerPanel" pref="53" max="32767" attributes="0"/>
|
||||||
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
@ -117,31 +117,28 @@
|
|||||||
<Layout>
|
<Layout>
|
||||||
<DimensionLayout dim="0">
|
<DimensionLayout dim="0">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" alignment="1" attributes="0">
|
<Component id="tableScrollPane" alignment="0" pref="1508" max="32767" attributes="0"/>
|
||||||
<Component id="tableStatusPanel" pref="1282" max="32767" attributes="0"/>
|
|
||||||
<EmptySpace min="-2" pref="218" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
<Component id="tableScrollPane" alignment="0" max="32767" attributes="0"/>
|
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Group type="102" alignment="0" attributes="0">
|
||||||
<Component id="earliestCaseLabel" min="-2" max="-2" attributes="0"/>
|
<Component id="earliestCaseLabel" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="-2" attributes="0"/>
|
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||||
<Component id="earliestCaseDate" min="-2" max="-2" attributes="0"/>
|
<Component id="earliestCaseDate" min="-2" max="-2" attributes="0"/>
|
||||||
<EmptySpace max="32767" attributes="0"/>
|
<EmptySpace min="-2" pref="66" max="-2" attributes="0"/>
|
||||||
|
<Component id="foundInLabel" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace min="0" pref="1157" max="32767" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
<DimensionLayout dim="1">
|
<DimensionLayout dim="1">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" alignment="1" attributes="0">
|
<Group type="102" alignment="1" attributes="0">
|
||||||
<Component id="tableScrollPane" pref="27" max="32767" attributes="0"/>
|
<Component id="tableScrollPane" pref="71" max="32767" attributes="0"/>
|
||||||
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
<Group type="103" groupAlignment="3" attributes="0">
|
<Group type="103" groupAlignment="3" attributes="0">
|
||||||
<Component id="earliestCaseLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="earliestCaseLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
<Component id="earliestCaseDate" alignment="3" min="-2" max="-2" attributes="0"/>
|
<Component id="earliestCaseDate" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="foundInLabel" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||||
</Group>
|
</Group>
|
||||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
<EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
|
||||||
<Component id="tableStatusPanel" min="-2" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
@ -198,26 +195,13 @@
|
|||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
</Component>
|
</Component>
|
||||||
<Container class="javax.swing.JPanel" name="tableStatusPanel">
|
<Component class="javax.swing.JLabel" name="foundInLabel">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
<Dimension value="[1500, 16]"/>
|
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/contentviewer/Bundle.properties" key="DataContentViewerOtherCases.foundInLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
</Property>
|
</Property>
|
||||||
</Properties>
|
</Properties>
|
||||||
|
</Component>
|
||||||
<Layout>
|
|
||||||
<DimensionLayout dim="0">
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</DimensionLayout>
|
|
||||||
<DimensionLayout dim="1">
|
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
|
||||||
<EmptySpace min="0" pref="16" max="32767" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</DimensionLayout>
|
|
||||||
</Layout>
|
|
||||||
</Container>
|
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Container>
|
</Container>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Central Repository
|
* Central Repository
|
||||||
*
|
*
|
||||||
* Copyright 2015-2018 Basis Technology Corp.
|
* Copyright 2015-2019 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -33,10 +33,12 @@ import java.util.ArrayList;
|
|||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import javax.swing.JFileChooser;
|
import javax.swing.JFileChooser;
|
||||||
@ -46,9 +48,13 @@ import static javax.swing.JOptionPane.DEFAULT_OPTION;
|
|||||||
import static javax.swing.JOptionPane.PLAIN_MESSAGE;
|
import static javax.swing.JOptionPane.PLAIN_MESSAGE;
|
||||||
import static javax.swing.JOptionPane.ERROR_MESSAGE;
|
import static javax.swing.JOptionPane.ERROR_MESSAGE;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.RowSorter;
|
||||||
|
import javax.swing.SortOrder;
|
||||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||||
import javax.swing.table.TableCellRenderer;
|
import javax.swing.table.TableCellRenderer;
|
||||||
import javax.swing.table.TableColumn;
|
import javax.swing.table.TableColumn;
|
||||||
|
import javax.swing.table.TableModel;
|
||||||
|
import javax.swing.table.TableRowSorter;
|
||||||
import org.joda.time.DateTimeZone;
|
import org.joda.time.DateTimeZone;
|
||||||
import org.joda.time.LocalDateTime;
|
import org.joda.time.LocalDateTime;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
@ -139,6 +145,19 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
|
|||||||
TableCellRenderer renderer = new DataContentViewerOtherCasesTableCellRenderer();
|
TableCellRenderer renderer = new DataContentViewerOtherCasesTableCellRenderer();
|
||||||
otherCasesTable.setDefaultRenderer(Object.class, renderer);
|
otherCasesTable.setDefaultRenderer(Object.class, renderer);
|
||||||
|
|
||||||
|
// Configure column sorting.
|
||||||
|
TableRowSorter<TableModel> sorter = new TableRowSorter<>(otherCasesTable.getModel());
|
||||||
|
otherCasesTable.setRowSorter(sorter);
|
||||||
|
List<RowSorter.SortKey> sortKeys = new ArrayList<>();
|
||||||
|
|
||||||
|
int caseNameColumnIndex = DataContentViewerOtherCasesTableModel.TableColumns.CASE_NAME.ordinal();
|
||||||
|
sortKeys.add(new RowSorter.SortKey(caseNameColumnIndex, SortOrder.ASCENDING));
|
||||||
|
|
||||||
|
int dataSourceColumnIndex = DataContentViewerOtherCasesTableModel.TableColumns.DATA_SOURCE.ordinal();
|
||||||
|
sortKeys.add(new RowSorter.SortKey(dataSourceColumnIndex, SortOrder.ASCENDING));
|
||||||
|
|
||||||
|
sorter.setSortKeys(sortKeys);
|
||||||
|
sorter.sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Messages({"DataContentViewerOtherCases.correlatedArtifacts.isEmpty=There are no files or artifacts to correlate.",
|
@Messages({"DataContentViewerOtherCases.correlatedArtifacts.isEmpty=There are no files or artifacts to correlate.",
|
||||||
@ -306,6 +325,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
|
|||||||
tableModel.clearTable();
|
tableModel.clearTable();
|
||||||
correlationAttributes.clear();
|
correlationAttributes.clear();
|
||||||
earliestCaseDate.setText(Bundle.DataContentViewerOtherCases_earliestCaseNotAvailable());
|
earliestCaseDate.setText(Bundle.DataContentViewerOtherCases_earliestCaseNotAvailable());
|
||||||
|
foundInLabel.setText("");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -338,6 +358,40 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the number of unique cases and data sources.
|
||||||
|
*/
|
||||||
|
@Messages({
|
||||||
|
"DataContentViewerOtherCases.foundIn.text=Found %d instances in %d cases and %d data sources."
|
||||||
|
})
|
||||||
|
private void setOccurrenceCounts() {
|
||||||
|
DataContentViewerOtherCasesTableModel model = (DataContentViewerOtherCasesTableModel) otherCasesTable.getModel();
|
||||||
|
|
||||||
|
int caseColumnIndex = DataContentViewerOtherCasesTableModel.TableColumns.CASE_NAME.ordinal();
|
||||||
|
int deviceColumnIndex = DataContentViewerOtherCasesTableModel.TableColumns.DEVICE.ordinal();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need a unique set of data sources. We rely on device ID for this.
|
||||||
|
* To mitigate edge cases where a device ID could be duplicated in the
|
||||||
|
* same case (e.g. "report.xml"), we put the device ID and case name in
|
||||||
|
* a key-value pair.
|
||||||
|
*
|
||||||
|
* Note: Relying on the case name isn't a fool-proof way of determining
|
||||||
|
* a case to be unique. We should improve this in the future.
|
||||||
|
*/
|
||||||
|
Set<String> cases = new HashSet<>();
|
||||||
|
Map<String, String> devices = new HashMap();
|
||||||
|
|
||||||
|
for (int i=0; i < model.getRowCount(); i++) {
|
||||||
|
String caseName = (String) model.getValueAt(i, caseColumnIndex);
|
||||||
|
String deviceId = (String) model.getValueAt(i, deviceColumnIndex);
|
||||||
|
cases.add(caseName);
|
||||||
|
devices.put(deviceId, caseName);
|
||||||
|
}
|
||||||
|
|
||||||
|
foundInLabel.setText(String.format(Bundle.DataContentViewerOtherCases_foundIn_text(), model.getRowCount(), cases.size(), devices.size()));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the associated BlackboardArtifact from a node, if it exists.
|
* Get the associated BlackboardArtifact from a node, if it exists.
|
||||||
*
|
*
|
||||||
@ -720,7 +774,9 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
|
|||||||
} else {
|
} else {
|
||||||
setColumnWidths();
|
setColumnWidths();
|
||||||
}
|
}
|
||||||
|
|
||||||
setEarliestCaseDate();
|
setEarliestCaseDate();
|
||||||
|
setOccurrenceCounts();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -772,7 +828,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
|
|||||||
otherCasesTable = new javax.swing.JTable();
|
otherCasesTable = new javax.swing.JTable();
|
||||||
earliestCaseLabel = new javax.swing.JLabel();
|
earliestCaseLabel = new javax.swing.JLabel();
|
||||||
earliestCaseDate = new javax.swing.JLabel();
|
earliestCaseDate = new javax.swing.JLabel();
|
||||||
tableStatusPanel = new javax.swing.JPanel();
|
foundInLabel = new javax.swing.JLabel();
|
||||||
|
|
||||||
rightClickPopupMenu.addPopupMenuListener(new javax.swing.event.PopupMenuListener() {
|
rightClickPopupMenu.addPopupMenuListener(new javax.swing.event.PopupMenuListener() {
|
||||||
public void popupMenuCanceled(javax.swing.event.PopupMenuEvent evt) {
|
public void popupMenuCanceled(javax.swing.event.PopupMenuEvent evt) {
|
||||||
@ -818,44 +874,31 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
|
|||||||
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(earliestCaseDate, org.openide.util.NbBundle.getMessage(DataContentViewerOtherCases.class, "DataContentViewerOtherCases.earliestCaseDate.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(earliestCaseDate, org.openide.util.NbBundle.getMessage(DataContentViewerOtherCases.class, "DataContentViewerOtherCases.earliestCaseDate.text")); // NOI18N
|
||||||
|
|
||||||
tableStatusPanel.setPreferredSize(new java.awt.Dimension(1500, 16));
|
org.openide.awt.Mnemonics.setLocalizedText(foundInLabel, org.openide.util.NbBundle.getMessage(DataContentViewerOtherCases.class, "DataContentViewerOtherCases.foundInLabel.text")); // NOI18N
|
||||||
|
|
||||||
javax.swing.GroupLayout tableStatusPanelLayout = new javax.swing.GroupLayout(tableStatusPanel);
|
|
||||||
tableStatusPanel.setLayout(tableStatusPanelLayout);
|
|
||||||
tableStatusPanelLayout.setHorizontalGroup(
|
|
||||||
tableStatusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addGap(0, 0, Short.MAX_VALUE)
|
|
||||||
);
|
|
||||||
tableStatusPanelLayout.setVerticalGroup(
|
|
||||||
tableStatusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addGap(0, 16, Short.MAX_VALUE)
|
|
||||||
);
|
|
||||||
|
|
||||||
javax.swing.GroupLayout tableContainerPanelLayout = new javax.swing.GroupLayout(tableContainerPanel);
|
javax.swing.GroupLayout tableContainerPanelLayout = new javax.swing.GroupLayout(tableContainerPanel);
|
||||||
tableContainerPanel.setLayout(tableContainerPanelLayout);
|
tableContainerPanel.setLayout(tableContainerPanelLayout);
|
||||||
tableContainerPanelLayout.setHorizontalGroup(
|
tableContainerPanelLayout.setHorizontalGroup(
|
||||||
tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, tableContainerPanelLayout.createSequentialGroup()
|
.addComponent(tableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 1508, Short.MAX_VALUE)
|
||||||
.addComponent(tableStatusPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 1282, Short.MAX_VALUE)
|
|
||||||
.addGap(218, 218, 218))
|
|
||||||
.addComponent(tableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
|
||||||
.addGroup(tableContainerPanelLayout.createSequentialGroup()
|
.addGroup(tableContainerPanelLayout.createSequentialGroup()
|
||||||
.addComponent(earliestCaseLabel)
|
.addComponent(earliestCaseLabel)
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||||
.addComponent(earliestCaseDate)
|
.addComponent(earliestCaseDate)
|
||||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
.addGap(66, 66, 66)
|
||||||
|
.addComponent(foundInLabel)
|
||||||
|
.addGap(0, 1157, Short.MAX_VALUE))
|
||||||
);
|
);
|
||||||
tableContainerPanelLayout.setVerticalGroup(
|
tableContainerPanelLayout.setVerticalGroup(
|
||||||
tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, tableContainerPanelLayout.createSequentialGroup()
|
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, tableContainerPanelLayout.createSequentialGroup()
|
||||||
.addComponent(tableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 27, Short.MAX_VALUE)
|
.addComponent(tableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 71, Short.MAX_VALUE)
|
||||||
.addGap(2, 2, 2)
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
.addGroup(tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
.addGroup(tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||||
.addComponent(earliestCaseLabel)
|
.addComponent(earliestCaseLabel)
|
||||||
.addComponent(earliestCaseDate))
|
.addComponent(earliestCaseDate)
|
||||||
.addGap(0, 0, 0)
|
.addComponent(foundInLabel))
|
||||||
.addComponent(tableStatusPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
.addGap(6, 6, 6))
|
||||||
.addGap(0, 0, 0))
|
|
||||||
);
|
);
|
||||||
|
|
||||||
javax.swing.GroupLayout otherCasesPanelLayout = new javax.swing.GroupLayout(otherCasesPanel);
|
javax.swing.GroupLayout otherCasesPanelLayout = new javax.swing.GroupLayout(otherCasesPanel);
|
||||||
@ -868,10 +911,10 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
|
|||||||
);
|
);
|
||||||
otherCasesPanelLayout.setVerticalGroup(
|
otherCasesPanelLayout.setVerticalGroup(
|
||||||
otherCasesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
otherCasesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGap(0, 483, Short.MAX_VALUE)
|
.addGap(0, 61, Short.MAX_VALUE)
|
||||||
.addGroup(otherCasesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
.addGroup(otherCasesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(otherCasesPanelLayout.createSequentialGroup()
|
.addGroup(otherCasesPanelLayout.createSequentialGroup()
|
||||||
.addComponent(tableContainerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 59, Short.MAX_VALUE)
|
.addComponent(tableContainerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 53, Short.MAX_VALUE)
|
||||||
.addGap(0, 0, 0)))
|
.addGap(0, 0, 0)))
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -883,7 +926,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
|
|||||||
);
|
);
|
||||||
layout.setVerticalGroup(
|
layout.setVerticalGroup(
|
||||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(otherCasesPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 59, Short.MAX_VALUE)
|
.addComponent(otherCasesPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 53, Short.MAX_VALUE)
|
||||||
);
|
);
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
@ -907,6 +950,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
|
|||||||
private javax.swing.JLabel earliestCaseDate;
|
private javax.swing.JLabel earliestCaseDate;
|
||||||
private javax.swing.JLabel earliestCaseLabel;
|
private javax.swing.JLabel earliestCaseLabel;
|
||||||
private javax.swing.JMenuItem exportToCSVMenuItem;
|
private javax.swing.JMenuItem exportToCSVMenuItem;
|
||||||
|
private javax.swing.JLabel foundInLabel;
|
||||||
private javax.swing.JPanel otherCasesPanel;
|
private javax.swing.JPanel otherCasesPanel;
|
||||||
private javax.swing.JTable otherCasesTable;
|
private javax.swing.JTable otherCasesTable;
|
||||||
private javax.swing.JPopupMenu rightClickPopupMenu;
|
private javax.swing.JPopupMenu rightClickPopupMenu;
|
||||||
@ -915,7 +959,6 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
|
|||||||
private javax.swing.JMenuItem showCommonalityMenuItem;
|
private javax.swing.JMenuItem showCommonalityMenuItem;
|
||||||
private javax.swing.JPanel tableContainerPanel;
|
private javax.swing.JPanel tableContainerPanel;
|
||||||
private javax.swing.JScrollPane tableScrollPane;
|
private javax.swing.JScrollPane tableScrollPane;
|
||||||
private javax.swing.JPanel tableStatusPanel;
|
|
||||||
// End of variables declaration//GEN-END:variables
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -83,3 +83,4 @@ MediaViewImagePanel.zoomResetButton.text=Reset
|
|||||||
MediaViewImagePanel.zoomTextField.text=
|
MediaViewImagePanel.zoomTextField.text=
|
||||||
MediaViewImagePanel.rotationTextField.text=
|
MediaViewImagePanel.rotationTextField.text=
|
||||||
MediaViewImagePanel.rotateLeftButton.toolTipText=
|
MediaViewImagePanel.rotateLeftButton.toolTipText=
|
||||||
|
HtmlPanel.showImagesToggleButton.text=Show Images
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||||
|
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
|
||||||
</AuxValues>
|
</AuxValues>
|
||||||
<LayoutCode>
|
<LayoutCode>
|
||||||
<CodeStatement>
|
<CodeStatement>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2018 Basis Technology Corp.
|
* Copyright 2018-2019 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -49,7 +49,8 @@ public class FileViewer extends javax.swing.JPanel implements DataContentViewer
|
|||||||
private final FileTypeViewer[] KNOWN_VIEWERS = new FileTypeViewer[]{
|
private final FileTypeViewer[] KNOWN_VIEWERS = new FileTypeViewer[]{
|
||||||
new SQLiteViewer(),
|
new SQLiteViewer(),
|
||||||
new PListViewer(),
|
new PListViewer(),
|
||||||
new MediaFileViewer()
|
new MediaFileViewer(),
|
||||||
|
new HtmlViewer()
|
||||||
};
|
};
|
||||||
|
|
||||||
private FileTypeViewer lastViewer;
|
private FileTypeViewer lastViewer;
|
||||||
|
65
Core/src/org/sleuthkit/autopsy/contentviewers/HtmlPanel.form
Executable file
65
Core/src/org/sleuthkit/autopsy/contentviewers/HtmlPanel.form
Executable file
@ -0,0 +1,65 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout>
|
||||||
|
<DimensionLayout dim="0">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Component id="htmlScrollPane" pref="300" max="32767" attributes="0"/>
|
||||||
|
<Group type="102" attributes="0">
|
||||||
|
<Component id="showImagesToggleButton" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
<DimensionLayout dim="1">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<Component id="showImagesToggleButton" min="-2" max="-2" attributes="0"/>
|
||||||
|
<EmptySpace max="-2" attributes="0"/>
|
||||||
|
<Component id="htmlScrollPane" pref="71" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
</Layout>
|
||||||
|
<SubComponents>
|
||||||
|
<Container class="javax.swing.JScrollPane" name="htmlScrollPane">
|
||||||
|
<Properties>
|
||||||
|
<Property name="verticalScrollBarPolicy" type="int" value="22"/>
|
||||||
|
</Properties>
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.JTextPane" name="htmlbodyTextPane">
|
||||||
|
<Properties>
|
||||||
|
<Property name="editable" type="boolean" value="false"/>
|
||||||
|
</Properties>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Container>
|
||||||
|
<Component class="javax.swing.JToggleButton" name="showImagesToggleButton">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="HtmlPanel.showImagesToggleButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="showImagesToggleButtonActionPerformed"/>
|
||||||
|
</Events>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Form>
|
165
Core/src/org/sleuthkit/autopsy/contentviewers/HtmlPanel.java
Executable file
165
Core/src/org/sleuthkit/autopsy/contentviewers/HtmlPanel.java
Executable file
@ -0,0 +1,165 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2019 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.contentviewers;
|
||||||
|
|
||||||
|
import org.jsoup.Jsoup;
|
||||||
|
import org.jsoup.nodes.Document;
|
||||||
|
import org.openide.util.NbBundle.Messages;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A file content viewer for HTML files.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
|
||||||
|
final class HtmlPanel extends javax.swing.JPanel {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private String htmlText;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new form HtmlViewerPanel
|
||||||
|
*/
|
||||||
|
HtmlPanel() {
|
||||||
|
initComponents();
|
||||||
|
|
||||||
|
Utilities.configureTextPaneAsHtml(htmlbodyTextPane);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the text pane's HTML text and refresh the view to display it.
|
||||||
|
*
|
||||||
|
* @param htmlText The HTML text to be applied to the text pane.
|
||||||
|
*/
|
||||||
|
void setHtmlText(String htmlText) {
|
||||||
|
this.htmlText = htmlText;
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the HTML in the text pane and disable the show/hide button.
|
||||||
|
*/
|
||||||
|
void reset() {
|
||||||
|
htmlbodyTextPane.setText("");
|
||||||
|
showImagesToggleButton.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Guarantee the HTML text has 'html' and 'body' tags.
|
||||||
|
*
|
||||||
|
* @param htmlText The HTML text
|
||||||
|
*
|
||||||
|
* @return The HTML text with the 'html' and 'body' tags applied.
|
||||||
|
*/
|
||||||
|
private String wrapInHtmlBody(String htmlText) {
|
||||||
|
return "<html><body>" + htmlText + "</body></html>";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleans out input HTML string
|
||||||
|
*
|
||||||
|
* @param htmlInString The HTML string to cleanse
|
||||||
|
*
|
||||||
|
* @return The cleansed HTML String
|
||||||
|
*/
|
||||||
|
private String cleanseHTML(String htmlInString) {
|
||||||
|
|
||||||
|
Document doc = Jsoup.parse(htmlInString);
|
||||||
|
|
||||||
|
// Update all 'img' tags.
|
||||||
|
doc.select("img[src]").forEach(img -> img.attr("src", ""));
|
||||||
|
|
||||||
|
return doc.html();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh the panel to reflect the current show/hide images setting.
|
||||||
|
*/
|
||||||
|
@Messages({
|
||||||
|
"HtmlPanel_showImagesToggleButton_show=Show Images",
|
||||||
|
"HtmlPanel_showImagesToggleButton_hide=Hide Images"
|
||||||
|
})
|
||||||
|
private void refresh() {
|
||||||
|
if (false == htmlText.isEmpty()) {
|
||||||
|
if (showImagesToggleButton.isSelected()) {
|
||||||
|
showImagesToggleButton.setText(Bundle.HtmlPanel_showImagesToggleButton_hide());
|
||||||
|
this.htmlbodyTextPane.setText(wrapInHtmlBody(htmlText));
|
||||||
|
} else {
|
||||||
|
showImagesToggleButton.setText(Bundle.HtmlPanel_showImagesToggleButton_show());
|
||||||
|
this.htmlbodyTextPane.setText(wrapInHtmlBody(cleanseHTML(htmlText)));
|
||||||
|
}
|
||||||
|
|
||||||
|
htmlbodyTextPane.setCaretPosition(0);
|
||||||
|
showImagesToggleButton.setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called from within the constructor to initialize the form.
|
||||||
|
* WARNING: Do NOT modify this code. The content of this method is always
|
||||||
|
* regenerated by the Form Editor.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||||
|
private void initComponents() {
|
||||||
|
|
||||||
|
htmlScrollPane = new javax.swing.JScrollPane();
|
||||||
|
htmlbodyTextPane = new javax.swing.JTextPane();
|
||||||
|
showImagesToggleButton = new javax.swing.JToggleButton();
|
||||||
|
|
||||||
|
htmlScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
|
||||||
|
|
||||||
|
htmlbodyTextPane.setEditable(false);
|
||||||
|
htmlScrollPane.setViewportView(htmlbodyTextPane);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(showImagesToggleButton, org.openide.util.NbBundle.getMessage(HtmlPanel.class, "HtmlPanel.showImagesToggleButton.text")); // NOI18N
|
||||||
|
showImagesToggleButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
showImagesToggleButtonActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
|
this.setLayout(layout);
|
||||||
|
layout.setHorizontalGroup(
|
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addComponent(htmlScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addComponent(showImagesToggleButton)
|
||||||
|
.addGap(0, 0, Short.MAX_VALUE))
|
||||||
|
);
|
||||||
|
layout.setVerticalGroup(
|
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addComponent(showImagesToggleButton)
|
||||||
|
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||||
|
.addComponent(htmlScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 71, Short.MAX_VALUE))
|
||||||
|
);
|
||||||
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
private void showImagesToggleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showImagesToggleButtonActionPerformed
|
||||||
|
refresh();
|
||||||
|
}//GEN-LAST:event_showImagesToggleButtonActionPerformed
|
||||||
|
|
||||||
|
|
||||||
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
private javax.swing.JScrollPane htmlScrollPane;
|
||||||
|
private javax.swing.JTextPane htmlbodyTextPane;
|
||||||
|
private javax.swing.JToggleButton showImagesToggleButton;
|
||||||
|
// End of variables declaration//GEN-END:variables
|
||||||
|
}
|
40
Core/src/org/sleuthkit/autopsy/contentviewers/HtmlViewer.form
Executable file
40
Core/src/org/sleuthkit/autopsy/contentviewers/HtmlViewer.form
Executable file
@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
|
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
|
<AuxValues>
|
||||||
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||||
|
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||||
|
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||||
|
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||||
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout>
|
||||||
|
<DimensionLayout dim="0">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="htmlPanel" max="32767" attributes="0"/>
|
||||||
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
<DimensionLayout dim="1">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<Group type="102" alignment="0" attributes="0">
|
||||||
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
|
<Component id="htmlPanel" max="32767" attributes="0"/>
|
||||||
|
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
</Layout>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="org.sleuthkit.autopsy.contentviewers.HtmlPanel" name="htmlPanel">
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Form>
|
128
Core/src/org/sleuthkit/autopsy/contentviewers/HtmlViewer.java
Executable file
128
Core/src/org/sleuthkit/autopsy/contentviewers/HtmlViewer.java
Executable file
@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2019 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.contentviewers;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Cursor;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import org.openide.windows.WindowManager;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A file content viewer for HTML files.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
|
||||||
|
final class HtmlViewer extends javax.swing.JPanel implements FileTypeViewer {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private static final Logger logger = Logger.getLogger(HtmlViewer.class.getName());
|
||||||
|
|
||||||
|
private static final String[] SUPPORTED_MIMETYPES = new String[]{
|
||||||
|
"text/html",
|
||||||
|
"application/xhtml+xml"
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new form HtmlViewerPanel
|
||||||
|
*/
|
||||||
|
HtmlViewer() {
|
||||||
|
initComponents();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the HTML text content from the supplied file.
|
||||||
|
*
|
||||||
|
* @param abstractFile The file to read.
|
||||||
|
*
|
||||||
|
* @return The text content of the file.
|
||||||
|
*/
|
||||||
|
private String getHtmlText(AbstractFile abstractFile) {
|
||||||
|
try {
|
||||||
|
int fileSize = (int) abstractFile.getSize();
|
||||||
|
byte[] buffer = new byte[fileSize];
|
||||||
|
abstractFile.read(buffer, 0, fileSize);
|
||||||
|
return new String(buffer);
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
logger.log(Level.SEVERE, String.format("Unable to read from file '%s' (id=%d).",
|
||||||
|
abstractFile.getName(), abstractFile.getId()), ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is called from within the constructor to initialize the form.
|
||||||
|
* WARNING: Do NOT modify this code. The content of this method is always
|
||||||
|
* regenerated by the Form Editor.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||||
|
private void initComponents() {
|
||||||
|
|
||||||
|
htmlPanel = new org.sleuthkit.autopsy.contentviewers.HtmlPanel();
|
||||||
|
|
||||||
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||||
|
this.setLayout(layout);
|
||||||
|
layout.setHorizontalGroup(
|
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addContainerGap()
|
||||||
|
.addComponent(htmlPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
|
.addContainerGap())
|
||||||
|
);
|
||||||
|
layout.setVerticalGroup(
|
||||||
|
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGroup(layout.createSequentialGroup()
|
||||||
|
.addContainerGap()
|
||||||
|
.addComponent(htmlPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
|
.addContainerGap())
|
||||||
|
);
|
||||||
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
|
||||||
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
private org.sleuthkit.autopsy.contentviewers.HtmlPanel htmlPanel;
|
||||||
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getSupportedMIMETypes() {
|
||||||
|
return Arrays.asList(SUPPORTED_MIMETYPES);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFile(AbstractFile file) {
|
||||||
|
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||||
|
htmlPanel.setHtmlText(getHtmlText(file));
|
||||||
|
WindowManager.getDefault().getMainWindow().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Component getComponent() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetComponent() {
|
||||||
|
htmlPanel.reset();
|
||||||
|
}
|
||||||
|
}
|
@ -126,7 +126,6 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan
|
|||||||
scene.getStylesheets().add(MediaViewImagePanel.class.getResource("MediaViewImagePanel.css").toExternalForm()); //NOI18N
|
scene.getStylesheets().add(MediaViewImagePanel.class.getResource("MediaViewImagePanel.css").toExternalForm()); //NOI18N
|
||||||
fxPanel.setScene(scene);
|
fxPanel.setScene(scene);
|
||||||
|
|
||||||
//bind size of image to that of scene, while keeping proportions
|
|
||||||
fxImageView.setSmooth(true);
|
fxImageView.setSmooth(true);
|
||||||
fxImageView.setCache(true);
|
fxImageView.setCache(true);
|
||||||
|
|
||||||
@ -142,11 +141,13 @@ class MediaViewImagePanel extends JPanel implements MediaFileViewer.MediaViewPan
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clear the displayed image
|
* Clear the displayed image
|
||||||
*/
|
*/
|
||||||
public void reset() {
|
public void reset() {
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
|
fxImageView.setViewport(new Rectangle2D(0, 0, 0, 0));
|
||||||
fxImageView.setImage(null);
|
fxImageView.setImage(null);
|
||||||
|
|
||||||
scrollPane.setContent(null);
|
scrollPane.setContent(null);
|
||||||
scrollPane.setContent(fxImageView);
|
scrollPane.setContent(fxImageView);
|
||||||
});
|
});
|
||||||
|
@ -274,50 +274,17 @@
|
|||||||
<Layout>
|
<Layout>
|
||||||
<DimensionLayout dim="0">
|
<DimensionLayout dim="0">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Component id="htmlScrollPane" alignment="0" max="32767" attributes="0"/>
|
<Component id="htmlPanel" alignment="0" pref="647" max="32767" attributes="0"/>
|
||||||
<Group type="102" alignment="1" attributes="0">
|
|
||||||
<EmptySpace pref="533" max="32767" attributes="0"/>
|
|
||||||
<Component id="showImagesToggleButton" min="-2" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace min="-2" pref="3" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
<DimensionLayout dim="1">
|
<DimensionLayout dim="1">
|
||||||
<Group type="103" groupAlignment="0" attributes="0">
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
<Group type="102" alignment="0" attributes="0">
|
<Component id="htmlPanel" alignment="0" pref="362" max="32767" attributes="0"/>
|
||||||
<Component id="showImagesToggleButton" min="-2" max="-2" attributes="0"/>
|
|
||||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
|
||||||
<Component id="htmlScrollPane" pref="333" max="32767" attributes="0"/>
|
|
||||||
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
|
|
||||||
</Group>
|
|
||||||
</Group>
|
</Group>
|
||||||
</DimensionLayout>
|
</DimensionLayout>
|
||||||
</Layout>
|
</Layout>
|
||||||
<SubComponents>
|
<SubComponents>
|
||||||
<Container class="javax.swing.JScrollPane" name="htmlScrollPane">
|
<Component class="org.sleuthkit.autopsy.contentviewers.HtmlPanel" name="htmlPanel">
|
||||||
<Properties>
|
|
||||||
<Property name="verticalScrollBarPolicy" type="int" value="22"/>
|
|
||||||
</Properties>
|
|
||||||
<AuxValues>
|
|
||||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
|
||||||
</AuxValues>
|
|
||||||
|
|
||||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
|
||||||
<SubComponents>
|
|
||||||
<Component class="javax.swing.JTextPane" name="htmlbodyTextPane">
|
|
||||||
<Properties>
|
|
||||||
<Property name="editable" type="boolean" value="false"/>
|
|
||||||
</Properties>
|
|
||||||
</Component>
|
|
||||||
</SubComponents>
|
|
||||||
</Container>
|
|
||||||
<Component class="javax.swing.JToggleButton" name="showImagesToggleButton">
|
|
||||||
<Properties>
|
|
||||||
<Property name="text" type="java.lang.String" value="Show Images"/>
|
|
||||||
</Properties>
|
|
||||||
<Events>
|
|
||||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="showImagesToggleButtonActionPerformed"/>
|
|
||||||
</Events>
|
|
||||||
</Component>
|
</Component>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Container>
|
</Container>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Autopsy Forensic Browser
|
* Autopsy Forensic Browser
|
||||||
*
|
*
|
||||||
* Copyright 2017-2018 Basis Technology Corp.
|
* Copyright 2017-2019 Basis Technology Corp.
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -106,9 +106,12 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont
|
|||||||
attachmentsScrollPane.setViewportView(drp);
|
attachmentsScrollPane.setViewportView(drp);
|
||||||
msgbodyTabbedPane.setEnabledAt(ATTM_TAB_INDEX, true);
|
msgbodyTabbedPane.setEnabledAt(ATTM_TAB_INDEX, true);
|
||||||
|
|
||||||
textAreas = Arrays.asList(headersTextArea, textbodyTextArea, htmlbodyTextPane, rtfbodyTextPane);
|
/*
|
||||||
|
* HTML tab uses the HtmlPanel instead of an internal text pane, so we
|
||||||
|
* use 'null' for that index.
|
||||||
|
*/
|
||||||
|
textAreas = Arrays.asList(headersTextArea, textbodyTextArea, null, rtfbodyTextPane);
|
||||||
|
|
||||||
Utilities.configureTextPaneAsHtml(htmlbodyTextPane);
|
|
||||||
Utilities.configureTextPaneAsRtf(rtfbodyTextPane);
|
Utilities.configureTextPaneAsRtf(rtfbodyTextPane);
|
||||||
resetComponent();
|
resetComponent();
|
||||||
|
|
||||||
@ -150,9 +153,7 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont
|
|||||||
textbodyScrollPane = new javax.swing.JScrollPane();
|
textbodyScrollPane = new javax.swing.JScrollPane();
|
||||||
textbodyTextArea = new javax.swing.JTextArea();
|
textbodyTextArea = new javax.swing.JTextArea();
|
||||||
htmlPane = new javax.swing.JPanel();
|
htmlPane = new javax.swing.JPanel();
|
||||||
htmlScrollPane = new javax.swing.JScrollPane();
|
htmlPanel = new org.sleuthkit.autopsy.contentviewers.HtmlPanel();
|
||||||
htmlbodyTextPane = new javax.swing.JTextPane();
|
|
||||||
showImagesToggleButton = new javax.swing.JToggleButton();
|
|
||||||
rtfbodyScrollPane = new javax.swing.JScrollPane();
|
rtfbodyScrollPane = new javax.swing.JScrollPane();
|
||||||
rtfbodyTextPane = new javax.swing.JTextPane();
|
rtfbodyTextPane = new javax.swing.JTextPane();
|
||||||
attachmentsPanel = new javax.swing.JPanel();
|
attachmentsPanel = new javax.swing.JPanel();
|
||||||
@ -265,35 +266,15 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont
|
|||||||
|
|
||||||
msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.textbodyScrollPane.TabConstraints.tabTitle"), textbodyScrollPane); // NOI18N
|
msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.textbodyScrollPane.TabConstraints.tabTitle"), textbodyScrollPane); // NOI18N
|
||||||
|
|
||||||
htmlScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
|
|
||||||
|
|
||||||
htmlbodyTextPane.setEditable(false);
|
|
||||||
htmlScrollPane.setViewportView(htmlbodyTextPane);
|
|
||||||
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(showImagesToggleButton, "Show Images");
|
|
||||||
showImagesToggleButton.addActionListener(new java.awt.event.ActionListener() {
|
|
||||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
|
||||||
showImagesToggleButtonActionPerformed(evt);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
javax.swing.GroupLayout htmlPaneLayout = new javax.swing.GroupLayout(htmlPane);
|
javax.swing.GroupLayout htmlPaneLayout = new javax.swing.GroupLayout(htmlPane);
|
||||||
htmlPane.setLayout(htmlPaneLayout);
|
htmlPane.setLayout(htmlPaneLayout);
|
||||||
htmlPaneLayout.setHorizontalGroup(
|
htmlPaneLayout.setHorizontalGroup(
|
||||||
htmlPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
htmlPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addComponent(htmlScrollPane)
|
.addComponent(htmlPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 647, Short.MAX_VALUE)
|
||||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, htmlPaneLayout.createSequentialGroup()
|
|
||||||
.addContainerGap(533, Short.MAX_VALUE)
|
|
||||||
.addComponent(showImagesToggleButton)
|
|
||||||
.addGap(3, 3, 3))
|
|
||||||
);
|
);
|
||||||
htmlPaneLayout.setVerticalGroup(
|
htmlPaneLayout.setVerticalGroup(
|
||||||
htmlPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
htmlPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
.addGroup(htmlPaneLayout.createSequentialGroup()
|
.addComponent(htmlPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 362, Short.MAX_VALUE)
|
||||||
.addComponent(showImagesToggleButton)
|
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
||||||
.addComponent(htmlScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 333, Short.MAX_VALUE)
|
|
||||||
.addGap(0, 0, 0))
|
|
||||||
);
|
);
|
||||||
|
|
||||||
msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.htmlPane.TabConstraints.tabTitle"), htmlPane); // NOI18N
|
msgbodyTabbedPane.addTab(org.openide.util.NbBundle.getMessage(MessageContentViewer.class, "MessageContentViewer.htmlPane.TabConstraints.tabTitle"), htmlPane); // NOI18N
|
||||||
@ -358,26 +339,6 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont
|
|||||||
);
|
);
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
@NbBundle.Messages({
|
|
||||||
"MessageContentViewer.showImagesToggleButton.hide.text=Hide Images",
|
|
||||||
"MessageContentViewer.showImagesToggleButton.text=Show Images"})
|
|
||||||
private void showImagesToggleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showImagesToggleButtonActionPerformed
|
|
||||||
try {
|
|
||||||
String htmlText = getAttributeValueSafe(artifact, TSK_EMAIL_CONTENT_HTML);
|
|
||||||
if (false == htmlText.isEmpty()) {
|
|
||||||
if (showImagesToggleButton.isSelected()) {
|
|
||||||
showImagesToggleButton.setText(Bundle.MessageContentViewer_showImagesToggleButton_hide_text());
|
|
||||||
this.htmlbodyTextPane.setText(wrapInHtmlBody(htmlText));
|
|
||||||
} else {
|
|
||||||
showImagesToggleButton.setText(Bundle.MessageContentViewer_showImagesToggleButton_text());
|
|
||||||
this.htmlbodyTextPane.setText(wrapInHtmlBody(cleanseHTML(htmlText)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (TskCoreException ex) {
|
|
||||||
LOGGER.log(Level.WARNING, "Failed to get attributes for email message.", ex); //NON-NLS
|
|
||||||
}
|
|
||||||
}//GEN-LAST:event_showImagesToggleButtonActionPerformed
|
|
||||||
|
|
||||||
private void viewInNewWindowButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewInNewWindowButtonActionPerformed
|
private void viewInNewWindowButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewInNewWindowButtonActionPerformed
|
||||||
new NewWindowViewAction("View in new window", drpExplorerManager.getSelectedNodes()[0]).actionPerformed(evt);
|
new NewWindowViewAction("View in new window", drpExplorerManager.getSelectedNodes()[0]).actionPerformed(evt);
|
||||||
}//GEN-LAST:event_viewInNewWindowButtonActionPerformed
|
}//GEN-LAST:event_viewInNewWindowButtonActionPerformed
|
||||||
@ -396,12 +357,10 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont
|
|||||||
private javax.swing.JScrollPane headersScrollPane;
|
private javax.swing.JScrollPane headersScrollPane;
|
||||||
private javax.swing.JTextArea headersTextArea;
|
private javax.swing.JTextArea headersTextArea;
|
||||||
private javax.swing.JPanel htmlPane;
|
private javax.swing.JPanel htmlPane;
|
||||||
private javax.swing.JScrollPane htmlScrollPane;
|
private org.sleuthkit.autopsy.contentviewers.HtmlPanel htmlPanel;
|
||||||
private javax.swing.JTextPane htmlbodyTextPane;
|
|
||||||
private javax.swing.JTabbedPane msgbodyTabbedPane;
|
private javax.swing.JTabbedPane msgbodyTabbedPane;
|
||||||
private javax.swing.JScrollPane rtfbodyScrollPane;
|
private javax.swing.JScrollPane rtfbodyScrollPane;
|
||||||
private javax.swing.JTextPane rtfbodyTextPane;
|
private javax.swing.JTextPane rtfbodyTextPane;
|
||||||
private javax.swing.JToggleButton showImagesToggleButton;
|
|
||||||
private javax.swing.JLabel subjectLabel;
|
private javax.swing.JLabel subjectLabel;
|
||||||
private javax.swing.JLabel subjectText;
|
private javax.swing.JLabel subjectText;
|
||||||
private javax.swing.JScrollPane textbodyScrollPane;
|
private javax.swing.JScrollPane textbodyScrollPane;
|
||||||
@ -505,9 +464,8 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont
|
|||||||
|
|
||||||
headersTextArea.setText("");
|
headersTextArea.setText("");
|
||||||
rtfbodyTextPane.setText("");
|
rtfbodyTextPane.setText("");
|
||||||
htmlbodyTextPane.setText("");
|
htmlPanel.reset();
|
||||||
textbodyTextArea.setText("");
|
textbodyTextArea.setText("");
|
||||||
showImagesToggleButton.setEnabled(false);
|
|
||||||
msgbodyTabbedPane.setEnabled(false);
|
msgbodyTabbedPane.setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -567,12 +525,15 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont
|
|||||||
String attributeText = getAttributeValueSafe(artifact, type);
|
String attributeText = getAttributeValueSafe(artifact, type);
|
||||||
|
|
||||||
if (index == HTML_TAB_INDEX && StringUtils.isNotBlank(attributeText)) {
|
if (index == HTML_TAB_INDEX && StringUtils.isNotBlank(attributeText)) {
|
||||||
//special case for HTML, we need to 'cleanse' it
|
htmlPanel.setHtmlText(attributeText);
|
||||||
attributeText = wrapInHtmlBody(cleanseHTML(attributeText));
|
} else {
|
||||||
|
JTextComponent textComponent = textAreas.get(index);
|
||||||
|
if (textComponent != null) {
|
||||||
|
textComponent.setText(attributeText);
|
||||||
|
textComponent.setCaretPosition(0); //make sure we start at the top
|
||||||
|
}
|
||||||
}
|
}
|
||||||
JTextComponent textComponent = textAreas.get(index);
|
|
||||||
textComponent.setText(attributeText);
|
|
||||||
textComponent.setCaretPosition(0); //make sure we start at the top
|
|
||||||
final boolean hasText = attributeText.length() > 0;
|
final boolean hasText = attributeText.length() > 0;
|
||||||
|
|
||||||
msgbodyTabbedPane.setEnabledAt(index, hasText);
|
msgbodyTabbedPane.setEnabledAt(index, hasText);
|
||||||
@ -613,10 +574,6 @@ public class MessageContentViewer extends javax.swing.JPanel implements DataCont
|
|||||||
directionText.setEnabled(false);
|
directionText.setEnabled(false);
|
||||||
ccLabel.setEnabled(true);
|
ccLabel.setEnabled(true);
|
||||||
|
|
||||||
showImagesToggleButton.setEnabled(true);
|
|
||||||
showImagesToggleButton.setText("Show Images");
|
|
||||||
showImagesToggleButton.setSelected(false);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.fromText.setText(getAttributeValueSafe(artifact, TSK_EMAIL_FROM));
|
this.fromText.setText(getAttributeValueSafe(artifact, TSK_EMAIL_FROM));
|
||||||
this.fromText.setToolTipText(getAttributeValueSafe(artifact, TSK_EMAIL_FROM));
|
this.fromText.setToolTipText(getAttributeValueSafe(artifact, TSK_EMAIL_FROM));
|
||||||
|
@ -302,8 +302,9 @@ class MSOfficeEmbeddedContentExtractor {
|
|||||||
}
|
}
|
||||||
List<ExtractedFile> listOfExtractedImages = new ArrayList<>();
|
List<ExtractedFile> listOfExtractedImages = new ArrayList<>();
|
||||||
byte[] data = null;
|
byte[] data = null;
|
||||||
|
int pictureNumber = 0; //added to ensure uniqueness in cases where suggestFullFileName returns duplicates
|
||||||
for (Picture picture : listOfAllPictures) {
|
for (Picture picture : listOfAllPictures) {
|
||||||
String fileName = picture.suggestFullFileName();
|
String fileName = UNKNOWN_IMAGE_NAME_PREFIX +pictureNumber +"."+ picture.suggestFileExtension();
|
||||||
try {
|
try {
|
||||||
data = picture.getContent();
|
data = picture.getContent();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
@ -312,6 +313,7 @@ class MSOfficeEmbeddedContentExtractor {
|
|||||||
writeExtractedImage(Paths.get(outputFolderPath, fileName).toString(), data);
|
writeExtractedImage(Paths.get(outputFolderPath, fileName).toString(), data);
|
||||||
// TODO Extract more info from the Picture viz ctime, crtime, atime, mtime
|
// TODO Extract more info from the Picture viz ctime, crtime, atime, mtime
|
||||||
listOfExtractedImages.add(new ExtractedFile(fileName, getFileRelativePath(fileName), picture.getSize()));
|
listOfExtractedImages.add(new ExtractedFile(fileName, getFileRelativePath(fileName), picture.getSize()));
|
||||||
|
pictureNumber++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return listOfExtractedImages;
|
return listOfExtractedImages;
|
||||||
|
@ -38,6 +38,9 @@ import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
|||||||
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||||
import org.sleuthkit.autopsy.datamodel.utils.FileTypeUtils.FileTypeCategory;
|
import org.sleuthkit.autopsy.datamodel.utils.FileTypeUtils.FileTypeCategory;
|
||||||
import org.sleuthkit.datamodel.AbstractFile;
|
import org.sleuthkit.datamodel.AbstractFile;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardArtifactTag;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
import org.sleuthkit.datamodel.Content;
|
import org.sleuthkit.datamodel.Content;
|
||||||
import org.sleuthkit.datamodel.ContentTag;
|
import org.sleuthkit.datamodel.ContentTag;
|
||||||
import org.sleuthkit.datamodel.FileSystem;
|
import org.sleuthkit.datamodel.FileSystem;
|
||||||
@ -47,6 +50,7 @@ import org.sleuthkit.datamodel.SleuthkitCase;
|
|||||||
import org.sleuthkit.datamodel.SleuthkitCase.CaseDbTransaction;
|
import org.sleuthkit.datamodel.SleuthkitCase.CaseDbTransaction;
|
||||||
import org.sleuthkit.datamodel.TagName;
|
import org.sleuthkit.datamodel.TagName;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
import org.sleuthkit.datamodel.TskDataException;
|
||||||
import org.sleuthkit.datamodel.TskData;
|
import org.sleuthkit.datamodel.TskData;
|
||||||
import org.sleuthkit.datamodel.Volume;
|
import org.sleuthkit.datamodel.Volume;
|
||||||
import org.sleuthkit.datamodel.VolumeSystem;
|
import org.sleuthkit.datamodel.VolumeSystem;
|
||||||
@ -66,7 +70,7 @@ public class CreatePortableCaseModule implements GeneralReportModule {
|
|||||||
FileTypeCategory.EXECUTABLE, FileTypeCategory.IMAGE, FileTypeCategory.VIDEO);
|
FileTypeCategory.EXECUTABLE, FileTypeCategory.IMAGE, FileTypeCategory.VIDEO);
|
||||||
|
|
||||||
private Case currentCase = null;
|
private Case currentCase = null;
|
||||||
private SleuthkitCase skCase = null;
|
private SleuthkitCase portableSkCase = null;
|
||||||
private File caseFolder = null;
|
private File caseFolder = null;
|
||||||
private File copiedFilesFolder = null;
|
private File copiedFilesFolder = null;
|
||||||
|
|
||||||
@ -79,6 +83,15 @@ public class CreatePortableCaseModule implements GeneralReportModule {
|
|||||||
// Maps old TagName to new TagName
|
// Maps old TagName to new TagName
|
||||||
private final Map<TagName, TagName> oldTagNameToNewTagName = new HashMap<>();
|
private final Map<TagName, TagName> oldTagNameToNewTagName = new HashMap<>();
|
||||||
|
|
||||||
|
// Map of old artifact type ID to new artifact type ID. There will only be changes if custom artifact types are present.
|
||||||
|
private final Map<Integer, Integer> oldArtTypeIdToNewArtTypeId = new HashMap<>();
|
||||||
|
|
||||||
|
// Map of old attribute type ID to new attribute type ID. There will only be changes if custom attr types are present.
|
||||||
|
private final Map<Integer, BlackboardAttribute.Type> oldAttrTypeIdToNewAttrType = new HashMap<>();
|
||||||
|
|
||||||
|
// Map of old artifact ID to new artifact
|
||||||
|
private final Map<Long, BlackboardArtifact> oldArtifactIdToNewArtifact = new HashMap<>();
|
||||||
|
|
||||||
public CreatePortableCaseModule() {
|
public CreatePortableCaseModule() {
|
||||||
// Nothing to do here
|
// Nothing to do here
|
||||||
}
|
}
|
||||||
@ -132,6 +145,8 @@ public class CreatePortableCaseModule implements GeneralReportModule {
|
|||||||
"CreatePortableCaseModule.generateReport.copyingTags=Copying tags...",
|
"CreatePortableCaseModule.generateReport.copyingTags=Copying tags...",
|
||||||
"# {0} - tag name",
|
"# {0} - tag name",
|
||||||
"CreatePortableCaseModule.generateReport.copyingFiles=Copying files tagged as {0}...",
|
"CreatePortableCaseModule.generateReport.copyingFiles=Copying files tagged as {0}...",
|
||||||
|
"# {0} - tag name",
|
||||||
|
"CreatePortableCaseModule.generateReport.copyingArtifacts=Copying artifacts tagged as {0}...",
|
||||||
"# {0} - output folder",
|
"# {0} - output folder",
|
||||||
"CreatePortableCaseModule.generateReport.outputDirDoesNotExist=Output folder {0} does not exist",
|
"CreatePortableCaseModule.generateReport.outputDirDoesNotExist=Output folder {0} does not exist",
|
||||||
"# {0} - output folder",
|
"# {0} - output folder",
|
||||||
@ -139,7 +154,10 @@ public class CreatePortableCaseModule implements GeneralReportModule {
|
|||||||
"CreatePortableCaseModule.generateReport.noTagsSelected=No tags selected for export.",
|
"CreatePortableCaseModule.generateReport.noTagsSelected=No tags selected for export.",
|
||||||
"CreatePortableCaseModule.generateReport.caseClosed=Current case has been closed",
|
"CreatePortableCaseModule.generateReport.caseClosed=Current case has been closed",
|
||||||
"CreatePortableCaseModule.generateReport.errorCopyingTags=Error copying tags",
|
"CreatePortableCaseModule.generateReport.errorCopyingTags=Error copying tags",
|
||||||
"CreatePortableCaseModule.generateReport.errorCopyingFiles=Error copying tagged files"
|
"CreatePortableCaseModule.generateReport.errorCopyingFiles=Error copying tagged files",
|
||||||
|
"CreatePortableCaseModule.generateReport.errorCopyingArtifacts=Error copying tagged artifacts",
|
||||||
|
"# {0} - attribute type name",
|
||||||
|
"CreatePortableCaseModule.generateReport.errorLookingUpAttrType=Error looking up attribute type {0}",
|
||||||
})
|
})
|
||||||
@Override
|
@Override
|
||||||
public void generateReport(String reportPath, ReportProgressPanel progressPanel) {
|
public void generateReport(String reportPath, ReportProgressPanel progressPanel) {
|
||||||
@ -182,10 +200,10 @@ public class CreatePortableCaseModule implements GeneralReportModule {
|
|||||||
|
|
||||||
|
|
||||||
// Create the case.
|
// Create the case.
|
||||||
// skCase and caseFolder will be set here.
|
// portableSkCase and caseFolder will be set here.
|
||||||
progressPanel.updateStatusLabel(Bundle.CreatePortableCaseModule_generateReport_creatingCase());
|
progressPanel.updateStatusLabel(Bundle.CreatePortableCaseModule_generateReport_creatingCase());
|
||||||
createCase(outputDir, progressPanel);
|
createCase(outputDir, progressPanel);
|
||||||
if (skCase == null) {
|
if (portableSkCase == null) {
|
||||||
// The error has already been handled
|
// The error has already been handled
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -200,7 +218,7 @@ public class CreatePortableCaseModule implements GeneralReportModule {
|
|||||||
progressPanel.updateStatusLabel(Bundle.CreatePortableCaseModule_generateReport_copyingTags());
|
progressPanel.updateStatusLabel(Bundle.CreatePortableCaseModule_generateReport_copyingTags());
|
||||||
try {
|
try {
|
||||||
for(TagName tagName:tagNames) {
|
for(TagName tagName:tagNames) {
|
||||||
TagName newTagName = skCase.addOrUpdateTagName(tagName.getDisplayName(), tagName.getDescription(), tagName.getColor(), tagName.getKnownStatus());
|
TagName newTagName = portableSkCase.addOrUpdateTagName(tagName.getDisplayName(), tagName.getDescription(), tagName.getColor(), tagName.getKnownStatus());
|
||||||
oldTagNameToNewTagName.put(tagName, newTagName);
|
oldTagNameToNewTagName.put(tagName, newTagName);
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
@ -223,6 +241,35 @@ public class CreatePortableCaseModule implements GeneralReportModule {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set up tracking to support any custom artifact or attribute types
|
||||||
|
for (BlackboardArtifact.ARTIFACT_TYPE type:BlackboardArtifact.ARTIFACT_TYPE.values()) {
|
||||||
|
oldArtTypeIdToNewArtTypeId.put(type.getTypeID(), type.getTypeID());
|
||||||
|
}
|
||||||
|
for (BlackboardAttribute.ATTRIBUTE_TYPE type:BlackboardAttribute.ATTRIBUTE_TYPE.values()) {
|
||||||
|
try {
|
||||||
|
oldAttrTypeIdToNewAttrType.put(type.getTypeID(), portableSkCase.getAttributeType(type.getLabel()));
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
handleError("Error looking up attribute name " + type.getLabel(),
|
||||||
|
Bundle.CreatePortableCaseModule_generateReport_errorLookingUpAttrType(type.getLabel()),
|
||||||
|
ex, progressPanel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the tagged artifacts and associated files
|
||||||
|
try {
|
||||||
|
for(TagName tagName:tagNames) {
|
||||||
|
// Check for cancellation
|
||||||
|
if (progressPanel.getStatus() == ReportProgressPanel.ReportStatus.CANCELED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
progressPanel.updateStatusLabel(Bundle.CreatePortableCaseModule_generateReport_copyingArtifacts(tagName.getDisplayName()));
|
||||||
|
addArtifactsToPortableCase(tagName, progressPanel);
|
||||||
|
}
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
handleError("Error copying tagged artifacts", Bundle.CreatePortableCaseModule_generateReport_errorCopyingArtifacts(), ex, progressPanel);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Close the case connections and clear out the maps
|
// Close the case connections and clear out the maps
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
@ -232,7 +279,7 @@ public class CreatePortableCaseModule implements GeneralReportModule {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the case directory and case database.
|
* Create the case directory and case database.
|
||||||
* skCase will be set if this completes without error.
|
* portableSkCase will be set if this completes without error.
|
||||||
*
|
*
|
||||||
* @param outputDir The parent for the case folder
|
* @param outputDir The parent for the case folder
|
||||||
* @param progressPanel
|
* @param progressPanel
|
||||||
@ -258,7 +305,7 @@ public class CreatePortableCaseModule implements GeneralReportModule {
|
|||||||
|
|
||||||
// Create the case
|
// Create the case
|
||||||
try {
|
try {
|
||||||
skCase = currentCase.createPortableCase(caseName, caseFolder);
|
portableSkCase = currentCase.createPortableCase(caseName, caseFolder);
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
handleError("Error creating case " + caseName + " in folder " + caseFolder.toString(),
|
handleError("Error creating case " + caseName + " in folder " + caseFolder.toString(),
|
||||||
Bundle.CreatePortableCaseModule_createCase_errorCreatingCase(), ex, progressPanel);
|
Bundle.CreatePortableCaseModule_createCase_errorCreatingCase(), ex, progressPanel);
|
||||||
@ -294,14 +341,11 @@ public class CreatePortableCaseModule implements GeneralReportModule {
|
|||||||
/**
|
/**
|
||||||
* Add all files with a given tag to the portable case.
|
* Add all files with a given tag to the portable case.
|
||||||
*
|
*
|
||||||
* @param oldTagName
|
* @param oldTagName The TagName object from the current case
|
||||||
* @param progressPanel
|
* @param progressPanel The progress panel
|
||||||
|
*
|
||||||
* @throws TskCoreException
|
* @throws TskCoreException
|
||||||
*/
|
*/
|
||||||
@NbBundle.Messages({
|
|
||||||
"# {0} - File name",
|
|
||||||
"CreatePortableCaseModule.addFilesToPortableCase.copyingFile=Copying file {0}",
|
|
||||||
})
|
|
||||||
private void addFilesToPortableCase(TagName oldTagName, ReportProgressPanel progressPanel) throws TskCoreException {
|
private void addFilesToPortableCase(TagName oldTagName, ReportProgressPanel progressPanel) throws TskCoreException {
|
||||||
|
|
||||||
// Get all the tags in the current case
|
// Get all the tags in the current case
|
||||||
@ -317,29 +361,201 @@ public class CreatePortableCaseModule implements GeneralReportModule {
|
|||||||
|
|
||||||
Content content = tag.getContent();
|
Content content = tag.getContent();
|
||||||
if (content instanceof AbstractFile) {
|
if (content instanceof AbstractFile) {
|
||||||
AbstractFile file = (AbstractFile) content;
|
long newFileId = copyContentToPortableCase(content, progressPanel);
|
||||||
String filePath = file.getParentPath() + file.getName();
|
|
||||||
progressPanel.updateStatusLabel(Bundle.CreatePortableCaseModule_addFilesToPortableCase_copyingFile(filePath));
|
|
||||||
|
|
||||||
long newFileId;
|
|
||||||
CaseDbTransaction trans = skCase.beginTransaction();
|
|
||||||
try {
|
|
||||||
newFileId = copyContent(file, trans);
|
|
||||||
trans.commit();
|
|
||||||
} catch (TskCoreException ex) {
|
|
||||||
trans.rollback();
|
|
||||||
throw(ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tag the file
|
// Tag the file
|
||||||
if (! oldTagNameToNewTagName.containsKey(tag.getName())) {
|
if (! oldTagNameToNewTagName.containsKey(tag.getName())) {
|
||||||
throw new TskCoreException("TagName map is missing entry for ID " + tag.getName().getId() + " with display name " + tag.getName().getDisplayName());
|
throw new TskCoreException("TagName map is missing entry for ID " + tag.getName().getId() + " with display name " + tag.getName().getDisplayName());
|
||||||
}
|
}
|
||||||
skCase.addContentTag(newIdToContent.get(newFileId), oldTagNameToNewTagName.get(tag.getName()), tag.getComment(), tag.getBeginByteOffset(), tag.getEndByteOffset());
|
portableSkCase.addContentTag(newIdToContent.get(newFileId), oldTagNameToNewTagName.get(tag.getName()), tag.getComment(), tag.getBeginByteOffset(), tag.getEndByteOffset());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add all artifacts with a given tag to the portable case.
|
||||||
|
*
|
||||||
|
* @param oldTagName The TagName object from the current case
|
||||||
|
* @param progressPanel The progress panel
|
||||||
|
*
|
||||||
|
* @throws TskCoreException
|
||||||
|
*/
|
||||||
|
private void addArtifactsToPortableCase(TagName oldTagName, ReportProgressPanel progressPanel) throws TskCoreException {
|
||||||
|
|
||||||
|
List<BlackboardArtifactTag> tags = currentCase.getServices().getTagsManager().getBlackboardArtifactTagsByTagName(oldTagName);
|
||||||
|
|
||||||
|
// Copy the artifacts into the portable case along with their content and tag
|
||||||
|
for (BlackboardArtifactTag tag : tags) {
|
||||||
|
|
||||||
|
// Check for cancellation
|
||||||
|
if (progressPanel.getStatus() == ReportProgressPanel.ReportStatus.CANCELED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the source content
|
||||||
|
Content content = tag.getContent();
|
||||||
|
long newContentId = copyContentToPortableCase(content, progressPanel);
|
||||||
|
|
||||||
|
// Copy the artifact
|
||||||
|
BlackboardArtifact newArtifact = copyArtifact(newContentId, tag.getArtifact());
|
||||||
|
|
||||||
|
// Tag the artfiact
|
||||||
|
if (! oldTagNameToNewTagName.containsKey(tag.getName())) {
|
||||||
|
throw new TskCoreException("TagName map is missing entry for ID " + tag.getName().getId() + " with display name " + tag.getName().getDisplayName());
|
||||||
|
}
|
||||||
|
portableSkCase.addBlackboardArtifactTag(newArtifact, oldTagNameToNewTagName.get(tag.getName()), tag.getComment());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy an artifact into the new case. Will also copy any associated artifacts
|
||||||
|
*
|
||||||
|
* @param newContentId The content ID (in the portable case) of the source content
|
||||||
|
* @param artifactToCopy The artifact to copy
|
||||||
|
*
|
||||||
|
* @return The new artifact in the portable case
|
||||||
|
*
|
||||||
|
* @throws TskCoreException
|
||||||
|
*/
|
||||||
|
private BlackboardArtifact copyArtifact(long newContentId, BlackboardArtifact artifactToCopy) throws TskCoreException {
|
||||||
|
|
||||||
|
if (oldArtifactIdToNewArtifact.containsKey(artifactToCopy.getArtifactID())) {
|
||||||
|
return oldArtifactIdToNewArtifact.get(artifactToCopy.getArtifactID());
|
||||||
|
}
|
||||||
|
|
||||||
|
// First create the associated artifact (if present)
|
||||||
|
BlackboardAttribute oldAssociatedAttribute = artifactToCopy.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT));
|
||||||
|
List<BlackboardAttribute> newAttrs = new ArrayList<>();
|
||||||
|
if (oldAssociatedAttribute != null) {
|
||||||
|
BlackboardArtifact oldAssociatedArtifact = currentCase.getSleuthkitCase().getBlackboardArtifact(oldAssociatedAttribute.getValueLong());
|
||||||
|
BlackboardArtifact newAssociatedArtifact = copyArtifact(newContentId, oldAssociatedArtifact);
|
||||||
|
newAttrs.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT,
|
||||||
|
String.join(",", oldAssociatedAttribute.getSources()), newAssociatedArtifact.getArtifactID()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the new artifact
|
||||||
|
int newArtifactTypeId = getNewArtifactTypeId(artifactToCopy);
|
||||||
|
BlackboardArtifact newArtifact = portableSkCase.newBlackboardArtifact(newArtifactTypeId, newContentId);
|
||||||
|
List<BlackboardAttribute> oldAttrs = artifactToCopy.getAttributes();
|
||||||
|
|
||||||
|
// Copy over each attribute, making sure the type is in the new case.
|
||||||
|
for (BlackboardAttribute oldAttr:oldAttrs) {
|
||||||
|
|
||||||
|
// The associated artifact has already been handled
|
||||||
|
if (oldAttr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlackboardAttribute.Type newAttributeType = getNewAttributeType(oldAttr);
|
||||||
|
switch (oldAttr.getValueType()) {
|
||||||
|
case BYTE:
|
||||||
|
newAttrs.add(new BlackboardAttribute(newAttributeType, String.join(",", oldAttr.getSources()),
|
||||||
|
oldAttr.getValueBytes()));
|
||||||
|
break;
|
||||||
|
case DOUBLE:
|
||||||
|
newAttrs.add(new BlackboardAttribute(newAttributeType, String.join(",", oldAttr.getSources()),
|
||||||
|
oldAttr.getValueDouble()));
|
||||||
|
break;
|
||||||
|
case INTEGER:
|
||||||
|
newAttrs.add(new BlackboardAttribute(newAttributeType, String.join(",", oldAttr.getSources()),
|
||||||
|
oldAttr.getValueInt()));
|
||||||
|
break;
|
||||||
|
case DATETIME:
|
||||||
|
case LONG:
|
||||||
|
newAttrs.add(new BlackboardAttribute(newAttributeType, String.join(",", oldAttr.getSources()),
|
||||||
|
oldAttr.getValueLong()));
|
||||||
|
break;
|
||||||
|
case STRING:
|
||||||
|
newAttrs.add(new BlackboardAttribute(newAttributeType, String.join(",", oldAttr.getSources()),
|
||||||
|
oldAttr.getValueString()));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new TskCoreException("Unexpected attribute value type found: " + oldAttr.getValueType().getLabel());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newArtifact.addAttributes(newAttrs);
|
||||||
|
|
||||||
|
oldArtifactIdToNewArtifact.put(artifactToCopy.getArtifactID(), newArtifact);
|
||||||
|
return newArtifact;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the artifact type ID in the portable case and create new artifact type if needed.
|
||||||
|
* For built-in artifacts this will be the same as the original.
|
||||||
|
*
|
||||||
|
* @param oldArtifactTypeId The artifact type ID in the current case
|
||||||
|
*
|
||||||
|
* @return The corresponding artifact type ID in the portable case
|
||||||
|
*/
|
||||||
|
private int getNewArtifactTypeId(BlackboardArtifact oldArtifact) throws TskCoreException {
|
||||||
|
if (oldArtTypeIdToNewArtTypeId.containsKey(oldArtifact.getArtifactTypeID())) {
|
||||||
|
return oldArtTypeIdToNewArtTypeId.get(oldArtifact.getArtifactTypeID());
|
||||||
|
}
|
||||||
|
|
||||||
|
BlackboardArtifact.Type oldCustomType = currentCase.getSleuthkitCase().getArtifactType(oldArtifact.getArtifactTypeName());
|
||||||
|
try {
|
||||||
|
BlackboardArtifact.Type newCustomType = portableSkCase.addBlackboardArtifactType(oldCustomType.getTypeName(), oldCustomType.getDisplayName());
|
||||||
|
oldArtTypeIdToNewArtTypeId.put(oldArtifact.getArtifactTypeID(), newCustomType.getTypeID());
|
||||||
|
return newCustomType.getTypeID();
|
||||||
|
} catch (TskDataException ex) {
|
||||||
|
throw new TskCoreException("Error creating new artifact type " + oldCustomType.getTypeName(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the attribute type ID in the portable case and create new attribute type if needed.
|
||||||
|
* For built-in attributes this will be the same as the original.
|
||||||
|
*
|
||||||
|
* @param oldAttributeTypeId The attribute type ID in the current case
|
||||||
|
*
|
||||||
|
* @return The corresponding attribute type in the portable case
|
||||||
|
*/
|
||||||
|
private BlackboardAttribute.Type getNewAttributeType(BlackboardAttribute oldAttribute) throws TskCoreException {
|
||||||
|
BlackboardAttribute.Type oldAttrType = oldAttribute.getAttributeType();
|
||||||
|
if (oldAttrTypeIdToNewAttrType.containsKey(oldAttrType.getTypeID())) {
|
||||||
|
return oldAttrTypeIdToNewAttrType.get(oldAttrType.getTypeID());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
BlackboardAttribute.Type newCustomType = portableSkCase.addArtifactAttributeType(oldAttrType.getTypeName(),
|
||||||
|
oldAttrType.getValueType(), oldAttrType.getDisplayName());
|
||||||
|
oldAttrTypeIdToNewAttrType.put(oldAttribute.getAttributeType().getTypeID(), newCustomType);
|
||||||
|
return newCustomType;
|
||||||
|
} catch (TskDataException ex) {
|
||||||
|
throw new TskCoreException("Error creating new attribute type " + oldAttrType.getTypeName(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Top level method to copy a content object to the portable case.
|
||||||
|
*
|
||||||
|
* @param content The content object to copy
|
||||||
|
* @param progressPanel The progress panel
|
||||||
|
*
|
||||||
|
* @return The object ID of the copied content in the portable case
|
||||||
|
*
|
||||||
|
* @throws TskCoreException
|
||||||
|
*/
|
||||||
|
@NbBundle.Messages({
|
||||||
|
"# {0} - File name",
|
||||||
|
"CreatePortableCaseModule.copyContentToPortableCase.copyingFile=Copying file {0}",
|
||||||
|
})
|
||||||
|
private long copyContentToPortableCase(Content content, ReportProgressPanel progressPanel) throws TskCoreException {
|
||||||
|
progressPanel.updateStatusLabel(Bundle.CreatePortableCaseModule_copyContentToPortableCase_copyingFile(content.getUniquePath()));
|
||||||
|
|
||||||
|
long newFileId;
|
||||||
|
CaseDbTransaction trans = portableSkCase.beginTransaction();
|
||||||
|
try {
|
||||||
|
newFileId = copyContent(content, trans);
|
||||||
|
trans.commit();
|
||||||
|
return newFileId;
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
trans.rollback();
|
||||||
|
throw(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the object ID for the given content object in the portable case.
|
* Returns the object ID for the given content object in the portable case.
|
||||||
*
|
*
|
||||||
@ -368,18 +584,18 @@ public class CreatePortableCaseModule implements GeneralReportModule {
|
|||||||
Content newContent;
|
Content newContent;
|
||||||
if (content instanceof Image) {
|
if (content instanceof Image) {
|
||||||
Image image = (Image)content;
|
Image image = (Image)content;
|
||||||
newContent = skCase.addImage(image.getType(), image.getSsize(), image.getSize(), image.getName(),
|
newContent = portableSkCase.addImage(image.getType(), image.getSsize(), image.getSize(), image.getName(),
|
||||||
new ArrayList<>(), image.getTimeZone(), image.getMd5(), image.getSha1(), image.getSha256(), image.getDeviceId(), trans);
|
new ArrayList<>(), image.getTimeZone(), image.getMd5(), image.getSha1(), image.getSha256(), image.getDeviceId(), trans);
|
||||||
} else if (content instanceof VolumeSystem) {
|
} else if (content instanceof VolumeSystem) {
|
||||||
VolumeSystem vs = (VolumeSystem)content;
|
VolumeSystem vs = (VolumeSystem)content;
|
||||||
newContent = skCase.addVolumeSystem(parentId, vs.getType(), vs.getOffset(), vs.getBlockSize(), trans);
|
newContent = portableSkCase.addVolumeSystem(parentId, vs.getType(), vs.getOffset(), vs.getBlockSize(), trans);
|
||||||
} else if (content instanceof Volume) {
|
} else if (content instanceof Volume) {
|
||||||
Volume vs = (Volume)content;
|
Volume vs = (Volume)content;
|
||||||
newContent = skCase.addVolume(parentId, vs.getAddr(), vs.getStart(), vs.getLength(),
|
newContent = portableSkCase.addVolume(parentId, vs.getAddr(), vs.getStart(), vs.getLength(),
|
||||||
vs.getDescription(), vs.getFlags(), trans);
|
vs.getDescription(), vs.getFlags(), trans);
|
||||||
} else if (content instanceof FileSystem) {
|
} else if (content instanceof FileSystem) {
|
||||||
FileSystem fs = (FileSystem)content;
|
FileSystem fs = (FileSystem)content;
|
||||||
newContent = skCase.addFileSystem(parentId, fs.getImageOffset(), fs.getFsType(), fs.getBlock_size(),
|
newContent = portableSkCase.addFileSystem(parentId, fs.getImageOffset(), fs.getFsType(), fs.getBlock_size(),
|
||||||
fs.getBlock_count(), fs.getRoot_inum(), fs.getFirst_inum(), fs.getLastInum(),
|
fs.getBlock_count(), fs.getRoot_inum(), fs.getFirst_inum(), fs.getLastInum(),
|
||||||
fs.getName(), trans);
|
fs.getName(), trans);
|
||||||
} else if (content instanceof AbstractFile) {
|
} else if (content instanceof AbstractFile) {
|
||||||
@ -387,10 +603,10 @@ public class CreatePortableCaseModule implements GeneralReportModule {
|
|||||||
|
|
||||||
if (abstractFile instanceof LocalFilesDataSource) {
|
if (abstractFile instanceof LocalFilesDataSource) {
|
||||||
LocalFilesDataSource localFilesDS = (LocalFilesDataSource)abstractFile;
|
LocalFilesDataSource localFilesDS = (LocalFilesDataSource)abstractFile;
|
||||||
newContent = skCase.addLocalFilesDataSource(localFilesDS.getDeviceId(), localFilesDS.getName(), localFilesDS.getTimeZone(), trans);
|
newContent = portableSkCase.addLocalFilesDataSource(localFilesDS.getDeviceId(), localFilesDS.getName(), localFilesDS.getTimeZone(), trans);
|
||||||
} else {
|
} else {
|
||||||
if (abstractFile.isDir()) {
|
if (abstractFile.isDir()) {
|
||||||
newContent = skCase.addLocalDirectory(parentId, abstractFile.getName(), trans);
|
newContent = portableSkCase.addLocalDirectory(parentId, abstractFile.getName(), trans);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
// Copy the file
|
// Copy the file
|
||||||
@ -410,7 +626,7 @@ public class CreatePortableCaseModule implements GeneralReportModule {
|
|||||||
// Construct the relative path to the copied file
|
// Construct the relative path to the copied file
|
||||||
String relativePath = FILE_FOLDER_NAME + File.separator + exportSubFolder + File.separator + fileName;
|
String relativePath = FILE_FOLDER_NAME + File.separator + exportSubFolder + File.separator + fileName;
|
||||||
|
|
||||||
newContent = skCase.addLocalFile(abstractFile.getName(), relativePath, abstractFile.getSize(),
|
newContent = portableSkCase.addLocalFile(abstractFile.getName(), relativePath, abstractFile.getSize(),
|
||||||
abstractFile.getCtime(), abstractFile.getCrtime(), abstractFile.getAtime(), abstractFile.getMtime(),
|
abstractFile.getCtime(), abstractFile.getCrtime(), abstractFile.getAtime(), abstractFile.getMtime(),
|
||||||
abstractFile.getMd5Hash(), abstractFile.getKnown(), abstractFile.getMIMEType(),
|
abstractFile.getMd5Hash(), abstractFile.getKnown(), abstractFile.getMIMEType(),
|
||||||
true, TskData.EncodingType.NONE,
|
true, TskData.EncodingType.NONE,
|
||||||
@ -459,9 +675,9 @@ public class CreatePortableCaseModule implements GeneralReportModule {
|
|||||||
newIdToContent.clear();
|
newIdToContent.clear();
|
||||||
oldTagNameToNewTagName.clear();
|
oldTagNameToNewTagName.clear();
|
||||||
currentCase = null;
|
currentCase = null;
|
||||||
if (skCase != null) {
|
if (portableSkCase != null) {
|
||||||
// We want to close the database connections here but it is currently not possible. JIRA-4736
|
// We want to close the database connections here but it is currently not possible. JIRA-4736
|
||||||
skCase = null;
|
portableSkCase = null;
|
||||||
}
|
}
|
||||||
caseFolder = null;
|
caseFolder = null;
|
||||||
copiedFilesFolder = null;
|
copiedFilesFolder = null;
|
||||||
|
@ -201,10 +201,21 @@ class AddArchiveTask implements Runnable {
|
|||||||
success = true;
|
success = true;
|
||||||
newDataSources.addAll(internalDataSource.getContent());
|
newDataSources.addAll(internalDataSource.getContent());
|
||||||
|
|
||||||
// Update the names for all new data sources to be the root archive plus the name of the data source
|
// update data source info
|
||||||
for (Content c:internalDataSource.getContent()) {
|
for (Content c:internalDataSource.getContent()) {
|
||||||
if (c instanceof DataSource) {
|
if (c instanceof DataSource) {
|
||||||
DataSource ds = (DataSource) c;
|
DataSource ds = (DataSource) c;
|
||||||
|
|
||||||
|
// Read existing aquisition details and update them
|
||||||
|
String details = "Extracted from archive: " + archivePath.toString();
|
||||||
|
String existingDetails = ds.getAcquisitionDetails();
|
||||||
|
if (existingDetails != null && !existingDetails.isEmpty()) {
|
||||||
|
ds.setAcquisitionDetails(existingDetails + System.getProperty("line.separator") + details);
|
||||||
|
} else {
|
||||||
|
ds.setAcquisitionDetails(details);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the names for all new data sources to be the root archive plus the name of the data source
|
||||||
String newName = Paths.get(archivePath).getFileName() + "/" + ds.getName();
|
String newName = Paths.get(archivePath).getFileName() + "/" + ds.getName();
|
||||||
ds.setDisplayName(newName);
|
ds.setDisplayName(newName);
|
||||||
currentCase.notifyDataSourceNameChanged(c, newName);
|
currentCase.notifyDataSourceNameChanged(c, newName);
|
||||||
@ -253,8 +264,17 @@ class AddArchiveTask implements Runnable {
|
|||||||
|
|
||||||
archiveDspLock.wait();
|
archiveDspLock.wait();
|
||||||
|
|
||||||
// at this point we got the content object(s) from the current DSP
|
// at this point we got the content object(s) from the current DSP.
|
||||||
newDataSources.addAll(internalDataSource.getContent());
|
newDataSources.addAll(internalDataSource.getContent());
|
||||||
|
|
||||||
|
for (Content c : internalDataSource.getContent()) {
|
||||||
|
if (c instanceof DataSource) {
|
||||||
|
DataSource ds = (DataSource) c;
|
||||||
|
// This is a new data source so just write the aquisition details
|
||||||
|
String details = "Extracted from archive: " + archivePath.toString();
|
||||||
|
ds.setAcquisitionDetails(details);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
|
@ -42,6 +42,7 @@ import org.netbeans.jellytools.NbDialogOperator;
|
|||||||
import org.netbeans.jellytools.WizardOperator;
|
import org.netbeans.jellytools.WizardOperator;
|
||||||
import org.netbeans.jemmy.JemmyProperties;
|
import org.netbeans.jemmy.JemmyProperties;
|
||||||
import org.netbeans.jemmy.Timeout;
|
import org.netbeans.jemmy.Timeout;
|
||||||
|
import org.netbeans.jemmy.TimeoutExpiredException;
|
||||||
import org.netbeans.jemmy.Timeouts;
|
import org.netbeans.jemmy.Timeouts;
|
||||||
import org.netbeans.jemmy.operators.JButtonOperator;
|
import org.netbeans.jemmy.operators.JButtonOperator;
|
||||||
import org.netbeans.jemmy.operators.JCheckBoxOperator;
|
import org.netbeans.jemmy.operators.JCheckBoxOperator;
|
||||||
@ -96,269 +97,333 @@ public class AutopsyTestCases {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testNewCaseWizardOpen(String title) {
|
public void testNewCaseWizardOpen(String title) {
|
||||||
logger.info("New Case");
|
try {
|
||||||
resetTimeouts("WindowWaiter.WaitWindowTimeout", 240000);
|
logger.info("New Case");
|
||||||
NbDialogOperator nbdo = new NbDialogOperator(title);
|
setTimeout("WindowWaiter.WaitWindowTimeout", 240000);
|
||||||
JButtonOperator jbo = new JButtonOperator(nbdo, 0); // the "New Case" button
|
NbDialogOperator nbdo = new NbDialogOperator(title);
|
||||||
jbo.pushNoBlock();
|
JButtonOperator jbo = new JButtonOperator(nbdo, 0); // the "New Case" button
|
||||||
|
jbo.pushNoBlock();
|
||||||
|
} catch (TimeoutExpiredException ex) {
|
||||||
|
screenshot("TimeoutScreenshot");
|
||||||
|
logger.log(Level.SEVERE, "AutopsyTestCases.testNewCaseWizard encountered timed out", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testNewCaseWizard() {
|
public void testNewCaseWizard() {
|
||||||
logger.info("New Case Wizard");
|
try {
|
||||||
WizardOperator wo = new WizardOperator("New Case Information");
|
logger.info("New Case Wizard");
|
||||||
JTextFieldOperator jtfo0 = new JTextFieldOperator(wo, 1);
|
WizardOperator wo = new WizardOperator("New Case Information");
|
||||||
jtfo0.typeText("AutopsyTestCase"); // Name the case "AutopsyTestCase"
|
JTextFieldOperator jtfo0 = new JTextFieldOperator(wo, 1);
|
||||||
JTextFieldOperator jtfo1 = new JTextFieldOperator(wo, 2);
|
jtfo0.typeText("AutopsyTestCase"); // Name the case "AutopsyTestCase"
|
||||||
jtfo1.typeText(getEscapedPath(System.getProperty("out_path")));
|
JTextFieldOperator jtfo1 = new JTextFieldOperator(wo, 2);
|
||||||
wo.btNext().clickMouse();
|
jtfo1.typeText(getEscapedPath(System.getProperty("out_path")));
|
||||||
JTextFieldOperator jtfo2 = new JTextFieldOperator(wo, 0);
|
wo.btNext().clickMouse();
|
||||||
jtfo2.typeText("000"); // Set the case number
|
JTextFieldOperator jtfo2 = new JTextFieldOperator(wo, 0);
|
||||||
JTextFieldOperator jtfo3 = new JTextFieldOperator(wo, 1);
|
jtfo2.typeText("000"); // Set the case number
|
||||||
jtfo3.typeText("Examiner 1"); // Set the case examiner
|
JTextFieldOperator jtfo3 = new JTextFieldOperator(wo, 1);
|
||||||
start = System.currentTimeMillis();
|
jtfo3.typeText("Examiner 1"); // Set the case examiner
|
||||||
wo.btFinish().clickMouse();
|
start = System.currentTimeMillis();
|
||||||
|
wo.btFinish().clickMouse();
|
||||||
|
} catch (TimeoutExpiredException ex) {
|
||||||
|
screenshot("TimeoutScreenshot");
|
||||||
|
logger.log(Level.SEVERE, "AutopsyTestCases.testNewCaseWizard encountered timed out", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testStartAddImageFileDataSource() {
|
public void testStartAddImageFileDataSource() {
|
||||||
/*
|
try {
|
||||||
* This time out is to give time for creating case database and opening solr index
|
/*
|
||||||
*/
|
* This time out is to give time for creating case database and
|
||||||
new Timeout("pausing", 120000).sleep();
|
* opening solr index
|
||||||
logger.info("Starting Add Image process");
|
*/
|
||||||
resetTimeouts("WindowWaiter.WaitWindowTimeOut", 240000);
|
new Timeout("pausing", 120000).sleep();
|
||||||
WizardOperator wo = new WizardOperator("Add Data Source");
|
logger.info("Starting Add Image process");
|
||||||
while(!wo.btNext().isEnabled()){
|
setTimeout("WindowWaiter.WaitWindowTimeOut", 240000);
|
||||||
new Timeout("pausing", 1000).sleep(); // give it a second till the Add Data Source dialog enabled
|
WizardOperator wo = new WizardOperator("Add Data Source");
|
||||||
|
while (!wo.btNext().isEnabled()) {
|
||||||
|
new Timeout("pausing", 1000).sleep(); // give it a second till the Add Data Source dialog enabled
|
||||||
|
}
|
||||||
|
//select the toggle button for Disk Image or VM File it will be the first button created and proceed to next panel
|
||||||
|
JToggleButtonOperator jtbo = new JToggleButtonOperator(wo, 0);
|
||||||
|
jtbo.clickMouse();
|
||||||
|
wo.btNext().clickMouse();
|
||||||
|
JTextFieldOperator jtfo0 = new JTextFieldOperator(wo, 0);
|
||||||
|
String img_path = getEscapedPath(System.getProperty("img_path"));
|
||||||
|
String imageDir = img_path;
|
||||||
|
((JTextComponent) jtfo0.getSource()).setText(imageDir);
|
||||||
|
JComboBoxOperator comboBoxOperator = new JComboBoxOperator(wo, 0);
|
||||||
|
comboBoxOperator.setSelectedItem("(GMT-5:00) America/New_York");
|
||||||
|
wo.btNext().clickMouse();
|
||||||
|
} catch (TimeoutExpiredException ex) {
|
||||||
|
screenshot("TimeoutScreenshot");
|
||||||
|
logger.log(Level.SEVERE, "AutopsyTestCases.testNewCaseWizard encountered timed out", ex);
|
||||||
}
|
}
|
||||||
//select the toggle button for Disk Image or VM File it will be the first button created and proceed to next panel
|
|
||||||
JToggleButtonOperator jtbo = new JToggleButtonOperator(wo, 0);
|
|
||||||
jtbo.clickMouse();
|
|
||||||
wo.btNext().clickMouse();
|
|
||||||
JTextFieldOperator jtfo0 = new JTextFieldOperator(wo, 0);
|
|
||||||
String img_path = getEscapedPath(System.getProperty("img_path"));
|
|
||||||
String imageDir = img_path;
|
|
||||||
((JTextComponent) jtfo0.getSource()).setText(imageDir);
|
|
||||||
JComboBoxOperator comboBoxOperator = new JComboBoxOperator(wo, 0);
|
|
||||||
comboBoxOperator.setSelectedItem("(GMT-5:00) America/New_York");
|
|
||||||
wo.btNext().clickMouse();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testStartAddLogicalFilesDataSource() {
|
public void testStartAddLogicalFilesDataSource() {
|
||||||
/*
|
try {
|
||||||
* This time out is to give time for creating case database and opening solr index
|
/*
|
||||||
*/
|
* This time out is to give time for creating case database and
|
||||||
new Timeout("pausing", 120000).sleep();
|
* opening solr index
|
||||||
logger.info("Starting Add Logical Files process");
|
*/
|
||||||
WizardOperator wo = new WizardOperator("Add Data Source");
|
new Timeout("pausing", 120000).sleep();
|
||||||
wo.setTimeouts(resetTimeouts("WindowWaiter.WaitWindowTimeOut", 240000));
|
logger.info("Starting Add Logical Files process");
|
||||||
while(!wo.btNext().isEnabled()){
|
WizardOperator wo = new WizardOperator("Add Data Source");
|
||||||
new Timeout("pausing", 1000).sleep(); // give it a second till the Add Data Source dialog enabled
|
wo.setTimeouts(setTimeout("WindowWaiter.WaitWindowTimeOut", 240000));
|
||||||
|
while (!wo.btNext().isEnabled()) {
|
||||||
|
new Timeout("pausing", 1000).sleep(); // give it a second till the Add Data Source dialog enabled
|
||||||
|
}
|
||||||
|
//select the toggle button for Logical Files it will be the third button created and proceed to next panel
|
||||||
|
JToggleButtonOperator jtbo = new JToggleButtonOperator(wo, 2);
|
||||||
|
jtbo.clickMouse();
|
||||||
|
wo.btNext().clickMouse();
|
||||||
|
JButtonOperator addButtonOperator = new JButtonOperator(wo, "Add");
|
||||||
|
addButtonOperator.pushNoBlock();
|
||||||
|
JFileChooserOperator fileChooserOperator = new JFileChooserOperator();
|
||||||
|
fileChooserOperator.setCurrentDirectory(new File(getEscapedPath(System.getProperty("img_path"))));
|
||||||
|
// set the current directory one level above the directory containing logicalFileSet folder.
|
||||||
|
fileChooserOperator.goUpLevel();
|
||||||
|
fileChooserOperator.chooseFile(new File(getEscapedPath(System.getProperty("img_path"))).getName());
|
||||||
|
wo.btNext().clickMouse();
|
||||||
|
} catch (TimeoutExpiredException ex) {
|
||||||
|
screenshot("TimeoutScreenshot");
|
||||||
|
logger.log(Level.SEVERE, "AutopsyTestCases.testNewCaseWizard encountered timed out", ex);
|
||||||
}
|
}
|
||||||
//select the toggle button for Logical Files it will be the third button created and proceed to next panel
|
|
||||||
JToggleButtonOperator jtbo = new JToggleButtonOperator(wo, 2);
|
|
||||||
jtbo.clickMouse();
|
|
||||||
wo.btNext().clickMouse();
|
|
||||||
JButtonOperator addButtonOperator = new JButtonOperator(wo, "Add");
|
|
||||||
addButtonOperator.pushNoBlock();
|
|
||||||
JFileChooserOperator fileChooserOperator = new JFileChooserOperator();
|
|
||||||
fileChooserOperator.setCurrentDirectory(new File(getEscapedPath(System.getProperty("img_path"))));
|
|
||||||
// set the current directory one level above the directory containing logicalFileSet folder.
|
|
||||||
fileChooserOperator.goUpLevel();
|
|
||||||
fileChooserOperator.chooseFile(new File(getEscapedPath(System.getProperty("img_path"))).getName());
|
|
||||||
wo.btNext().clickMouse();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testAddSourceWizard1() {
|
public void testAddSourceWizard1() {
|
||||||
WizardOperator wo = new WizardOperator("Add Data Source");
|
try {
|
||||||
while (!wo.btFinish().isEnabled()) {
|
WizardOperator wo = new WizardOperator("Add Data Source");
|
||||||
new Timeout("pausing", 1000).sleep(); // give it a second (or five) to process
|
while (!wo.btFinish().isEnabled()) {
|
||||||
|
new Timeout("pausing", 1000).sleep(); // give it a second (or five) to process
|
||||||
|
}
|
||||||
|
logger.log(Level.INFO, "Add image took {0}ms", (System.currentTimeMillis() - start));
|
||||||
|
wo.btFinish().clickMouse();
|
||||||
|
} catch (TimeoutExpiredException ex) {
|
||||||
|
screenshot("TimeoutScreenshot");
|
||||||
|
logger.log(Level.SEVERE, "AutopsyTestCases.testNewCaseWizard encountered timed out", ex);
|
||||||
}
|
}
|
||||||
logger.log(Level.INFO, "Add image took {0}ms", (System.currentTimeMillis() - start));
|
|
||||||
wo.btFinish().clickMouse();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testConfigureIngest1() {
|
public void testConfigureIngest1() {
|
||||||
/*
|
try {
|
||||||
* This timeout is to allow the setup for the ingest job settings panel
|
/*
|
||||||
* to complete.
|
* This timeout is to allow the setup for the ingest job settings
|
||||||
*/
|
* panel to complete.
|
||||||
new Timeout("pausing", 10000).sleep();
|
*/
|
||||||
|
new Timeout("pausing", 10000).sleep();
|
||||||
|
|
||||||
logger.info("Looking for hash lookup module in ingest job settings panel");
|
logger.info("Looking for hash lookup module in ingest job settings panel");
|
||||||
WizardOperator wo = new WizardOperator("Add Data Source");
|
WizardOperator wo = new WizardOperator("Add Data Source");
|
||||||
while(!wo.btNext().isEnabled()){
|
while (!wo.btNext().isEnabled()) {
|
||||||
new Timeout("pausing", 1000).sleep(); // give it a second till the Add Data Source dialog enabled
|
new Timeout("pausing", 1000).sleep(); // give it a second till the Add Data Source dialog enabled
|
||||||
|
}
|
||||||
|
JTableOperator jto = new JTableOperator(wo, 0);
|
||||||
|
int row = jto.findCellRow("Hash Lookup", 2, 0);
|
||||||
|
jto.clickOnCell(row, 1);
|
||||||
|
logger.info("Selected hash lookup module in ingest job settings panel");
|
||||||
|
JButtonOperator jbo1 = new JButtonOperator(wo, "Global Settings");
|
||||||
|
jbo1.pushNoBlock();
|
||||||
|
logger.info("Pushed Global Settings button for hash lookup module in ingest job settings panel");
|
||||||
|
} catch (TimeoutExpiredException ex) {
|
||||||
|
screenshot("TimeoutScreenshot");
|
||||||
|
logger.log(Level.SEVERE, "AutopsyTestCases.testNewCaseWizard encountered timed out", ex);
|
||||||
}
|
}
|
||||||
JTableOperator jto = new JTableOperator(wo, 0);
|
|
||||||
int row = jto.findCellRow("Hash Lookup", 2, 0);
|
|
||||||
jto.clickOnCell(row, 1);
|
|
||||||
logger.info("Selected hash lookup module in ingest job settings panel");
|
|
||||||
JButtonOperator jbo1 = new JButtonOperator(wo, "Global Settings");
|
|
||||||
jbo1.pushNoBlock();
|
|
||||||
logger.info("Pushed Global Settings button for hash lookup module in ingest job settings panel");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testConfigureHash() {
|
public void testConfigureHash() {
|
||||||
logger.info("Hash Configure");
|
try {
|
||||||
JDialog hashMainDialog = JDialogOperator.waitJDialog("Global Hash Lookup Settings", false, false);
|
logger.info("Hash Configure");
|
||||||
JDialogOperator hashMainDialogOperator = new JDialogOperator(hashMainDialog);
|
JDialog hashMainDialog = JDialogOperator.waitJDialog("Global Hash Lookup Settings", false, false);
|
||||||
List<String> databases = new ArrayList<>();
|
JDialogOperator hashMainDialogOperator = new JDialogOperator(hashMainDialog);
|
||||||
databases.add(getEscapedPath(System.getProperty("nsrl_path")));
|
List<String> databases = new ArrayList<>();
|
||||||
databases.add(getEscapedPath(System.getProperty("known_bad_path")));
|
databases.add(getEscapedPath(System.getProperty("nsrl_path")));
|
||||||
databases.stream().map((database) -> {
|
databases.add(getEscapedPath(System.getProperty("known_bad_path")));
|
||||||
JButtonOperator importButtonOperator = new JButtonOperator(hashMainDialogOperator, "Import");
|
databases.stream().map((database) -> {
|
||||||
importButtonOperator.pushNoBlock();
|
JButtonOperator importButtonOperator = new JButtonOperator(hashMainDialogOperator, "Import");
|
||||||
JDialog addDatabaseDialog = JDialogOperator.waitJDialog("Import Hash Set", false, false);
|
importButtonOperator.pushNoBlock();
|
||||||
JDialogOperator addDatabaseDialogOperator = new JDialogOperator(addDatabaseDialog);
|
JDialog addDatabaseDialog = JDialogOperator.waitJDialog("Import Hash Set", false, false);
|
||||||
JButtonOperator browseButtonOperator = new JButtonOperator(addDatabaseDialogOperator, "Open...", 0);
|
JDialogOperator addDatabaseDialogOperator = new JDialogOperator(addDatabaseDialog);
|
||||||
browseButtonOperator.pushNoBlock();
|
JButtonOperator browseButtonOperator = new JButtonOperator(addDatabaseDialogOperator, "Open...", 0);
|
||||||
JFileChooserOperator fileChooserOperator = new JFileChooserOperator();
|
browseButtonOperator.pushNoBlock();
|
||||||
fileChooserOperator.chooseFile(database);
|
JFileChooserOperator fileChooserOperator = new JFileChooserOperator();
|
||||||
JButtonOperator okButtonOperator = new JButtonOperator(addDatabaseDialogOperator, "OK", 0);
|
fileChooserOperator.chooseFile(database);
|
||||||
return okButtonOperator;
|
JButtonOperator okButtonOperator = new JButtonOperator(addDatabaseDialogOperator, "OK", 0);
|
||||||
}).map((okButtonOperator) -> {
|
return okButtonOperator;
|
||||||
okButtonOperator.pushNoBlock();
|
}).map((okButtonOperator) -> {
|
||||||
return okButtonOperator;
|
okButtonOperator.pushNoBlock();
|
||||||
}).forEach((_item) -> {
|
return okButtonOperator;
|
||||||
|
}).forEach((_item) -> {
|
||||||
|
new Timeout("pausing", 1000).sleep(); // give it a second (or five) to process
|
||||||
|
});
|
||||||
|
// Used if the database has no index
|
||||||
|
//JDialog jd3 = JDialogOperator.waitJDialog("No Index Exists", false, false);
|
||||||
|
//JDialogOperator jdo3 = new JDialogOperator(jd3);
|
||||||
|
//JButtonOperator jbo3 = new JButtonOperator(jdo3, "Yes", 0);
|
||||||
new Timeout("pausing", 1000).sleep(); // give it a second (or five) to process
|
new Timeout("pausing", 1000).sleep(); // give it a second (or five) to process
|
||||||
});
|
//jbo3.pushNoBlock();
|
||||||
// Used if the database has no index
|
JButtonOperator jbo4 = new JButtonOperator(hashMainDialogOperator, "OK", 0);
|
||||||
//JDialog jd3 = JDialogOperator.waitJDialog("No Index Exists", false, false);
|
jbo4.pushNoBlock();
|
||||||
//JDialogOperator jdo3 = new JDialogOperator(jd3);
|
} catch (TimeoutExpiredException ex) {
|
||||||
//JButtonOperator jbo3 = new JButtonOperator(jdo3, "Yes", 0);
|
screenshot("TimeoutScreenshot");
|
||||||
new Timeout("pausing", 1000).sleep(); // give it a second (or five) to process
|
logger.log(Level.SEVERE, "AutopsyTestCases.testNewCaseWizard encountered timed out", ex);
|
||||||
//jbo3.pushNoBlock();
|
}
|
||||||
JButtonOperator jbo4 = new JButtonOperator(hashMainDialogOperator, "OK", 0);
|
|
||||||
jbo4.pushNoBlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testConfigureIngest2() {
|
public void testConfigureIngest2() {
|
||||||
logger.info("Looking for keyword search module in ingest job settings panel");
|
try {
|
||||||
WizardOperator wo = new WizardOperator("Add Data Source");
|
logger.info("Looking for keyword search module in ingest job settings panel");
|
||||||
while(!wo.btNext().isEnabled()){
|
WizardOperator wo = new WizardOperator("Add Data Source");
|
||||||
new Timeout("pausing", 1000).sleep(); // give it a second till the Add Data Source dialog enabled
|
while (!wo.btNext().isEnabled()) {
|
||||||
|
new Timeout("pausing", 1000).sleep(); // give it a second till the Add Data Source dialog enabled
|
||||||
|
}
|
||||||
|
JTableOperator jto = new JTableOperator(wo, 0);
|
||||||
|
int row = jto.findCellRow("Keyword Search", 2, 0);
|
||||||
|
jto.clickOnCell(row, 1);
|
||||||
|
logger.info("Selected keyword search module in ingest job settings panel");
|
||||||
|
JButtonOperator jbo1 = new JButtonOperator(wo, "Global Settings");
|
||||||
|
jbo1.pushNoBlock();
|
||||||
|
logger.info("Pushed Global Settings button for keyword search module in ingest job settings panel");
|
||||||
|
} catch (TimeoutExpiredException ex) {
|
||||||
|
screenshot("TimeoutScreenshot");
|
||||||
|
logger.log(Level.SEVERE, "AutopsyTestCases.testNewCaseWizard encountered timed out", ex);
|
||||||
}
|
}
|
||||||
JTableOperator jto = new JTableOperator(wo, 0);
|
|
||||||
int row = jto.findCellRow("Keyword Search", 2, 0);
|
|
||||||
jto.clickOnCell(row, 1);
|
|
||||||
logger.info("Selected keyword search module in ingest job settings panel");
|
|
||||||
JButtonOperator jbo1 = new JButtonOperator(wo, "Global Settings");
|
|
||||||
jbo1.pushNoBlock();
|
|
||||||
logger.info("Pushed Global Settings button for keyword search module in ingest job settings panel");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testConfigureSearch() {
|
public void testConfigureSearch() {
|
||||||
logger.info("Search Configure");
|
try {
|
||||||
JDialog jd = JDialogOperator.waitJDialog("Global Keyword Search Settings", false, false);
|
logger.info("Search Configure");
|
||||||
JDialogOperator jdo = new JDialogOperator(jd);
|
JDialog jd = JDialogOperator.waitJDialog("Global Keyword Search Settings", false, false);
|
||||||
String words = getEscapedPath(System.getProperty("keyword_path"));
|
JDialogOperator jdo = new JDialogOperator(jd);
|
||||||
JButtonOperator jbo0 = new JButtonOperator(jdo, "Import List", 0);
|
String words = getEscapedPath(System.getProperty("keyword_path"));
|
||||||
jbo0.pushNoBlock();
|
JButtonOperator jbo0 = new JButtonOperator(jdo, "Import List", 0);
|
||||||
JFileChooserOperator jfco0 = new JFileChooserOperator();
|
jbo0.pushNoBlock();
|
||||||
jfco0.chooseFile(words);
|
JFileChooserOperator jfco0 = new JFileChooserOperator();
|
||||||
JTableOperator jto = new JTableOperator(jdo, 0);
|
jfco0.chooseFile(words);
|
||||||
jto.clickOnCell(0, 0);
|
JTableOperator jto = new JTableOperator(jdo, 0);
|
||||||
new Timeout("pausing", 1000).sleep(); // give it a second to process
|
jto.clickOnCell(0, 0);
|
||||||
if (Boolean.parseBoolean(System.getProperty("mugen_mode"))) {
|
|
||||||
JTabbedPaneOperator jtpo = new JTabbedPaneOperator(jdo);
|
|
||||||
jtpo.selectPage("String Extraction");
|
|
||||||
JCheckBoxOperator jcbo0 = new JCheckBoxOperator(jtpo, "Arabic (Arabic)");
|
|
||||||
jcbo0.doClick();
|
|
||||||
JCheckBoxOperator jcbo1 = new JCheckBoxOperator(jtpo, "Han (Chinese, Japanese, Korean)");
|
|
||||||
jcbo1.doClick();
|
|
||||||
new Timeout("pausing", 1000).sleep(); // give it a second to process
|
new Timeout("pausing", 1000).sleep(); // give it a second to process
|
||||||
|
if (Boolean.parseBoolean(System.getProperty("mugen_mode"))) {
|
||||||
|
JTabbedPaneOperator jtpo = new JTabbedPaneOperator(jdo);
|
||||||
|
jtpo.selectPage("String Extraction");
|
||||||
|
JCheckBoxOperator jcbo0 = new JCheckBoxOperator(jtpo, "Arabic (Arabic)");
|
||||||
|
jcbo0.doClick();
|
||||||
|
JCheckBoxOperator jcbo1 = new JCheckBoxOperator(jtpo, "Han (Chinese, Japanese, Korean)");
|
||||||
|
jcbo1.doClick();
|
||||||
|
new Timeout("pausing", 1000).sleep(); // give it a second to process
|
||||||
|
}
|
||||||
|
JButtonOperator jbo2 = new JButtonOperator(jdo, "OK", 0);
|
||||||
|
jbo2.pushNoBlock();
|
||||||
|
WizardOperator wo = new WizardOperator("Add Data Source");
|
||||||
|
new Timeout("pausing", 10000).sleep(); // let things catch up
|
||||||
|
wo.btNext().clickMouse();
|
||||||
|
} catch (TimeoutExpiredException ex) {
|
||||||
|
screenshot("TimeoutScreenshot");
|
||||||
|
logger.log(Level.SEVERE, "AutopsyTestCases.testNewCaseWizard encountered timed out", ex);
|
||||||
}
|
}
|
||||||
JButtonOperator jbo2 = new JButtonOperator(jdo, "OK", 0);
|
|
||||||
jbo2.pushNoBlock();
|
|
||||||
WizardOperator wo = new WizardOperator("Add Data Source");
|
|
||||||
new Timeout("pausing", 10000).sleep(); // let things catch up
|
|
||||||
wo.btNext().clickMouse();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testIngest() {
|
public void testIngest() {
|
||||||
logger.info("Ingest 3");
|
try {
|
||||||
new Timeout("pausing", 10000).sleep(); // wait for ingest to actually start
|
logger.info("Ingest 3");
|
||||||
long startIngest = System.currentTimeMillis();
|
new Timeout("pausing", 10000).sleep(); // wait for ingest to actually start
|
||||||
IngestManager man = IngestManager.getInstance();
|
long startIngest = System.currentTimeMillis();
|
||||||
while (man.isIngestRunning()) {
|
IngestManager man = IngestManager.getInstance();
|
||||||
new Timeout("pausing", 1000).sleep(); // give it a second (or five) to process
|
while (man.isIngestRunning()) {
|
||||||
|
new Timeout("pausing", 1000).sleep(); // give it a second (or five) to process
|
||||||
|
}
|
||||||
|
logger.log(Level.INFO, "Ingest (including enqueue) took {0}ms", (System.currentTimeMillis() - startIngest));
|
||||||
|
// allow keyword search to finish saving artifacts, just in case
|
||||||
|
// but randomize the timing so that we don't always get the same error
|
||||||
|
// consistently, making it seem like default behavior
|
||||||
|
Random rand = new Random();
|
||||||
|
new Timeout("pausing", 10000 + (rand.nextInt(15000) + 5000)).sleep();
|
||||||
|
} catch (TimeoutExpiredException ex) {
|
||||||
|
screenshot("TimeoutScreenshot");
|
||||||
|
logger.log(Level.SEVERE, "AutopsyTestCases.testNewCaseWizard encountered timed out", ex);
|
||||||
}
|
}
|
||||||
logger.log(Level.INFO, "Ingest (including enqueue) took {0}ms", (System.currentTimeMillis() - startIngest));
|
|
||||||
// allow keyword search to finish saving artifacts, just in case
|
|
||||||
// but randomize the timing so that we don't always get the same error
|
|
||||||
// consistently, making it seem like default behavior
|
|
||||||
Random rand = new Random();
|
|
||||||
new Timeout("pausing", 10000 + (rand.nextInt(15000) + 5000)).sleep();
|
|
||||||
screenshot("Finished Ingest");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testExpandDataSourcesTree() {
|
public void testExpandDataSourcesTree() {
|
||||||
logger.info("Data Sources Node");
|
try {
|
||||||
MainWindowOperator mwo = MainWindowOperator.getDefault();
|
logger.info("Data Sources Node");
|
||||||
JTreeOperator jto = new JTreeOperator(mwo, "Data Sources");
|
MainWindowOperator mwo = MainWindowOperator.getDefault();
|
||||||
String [] nodeNames = {"Data Sources"};
|
JTreeOperator jto = new JTreeOperator(mwo, "Data Sources");
|
||||||
TreePath tp = jto.findPath(nodeNames);
|
String[] nodeNames = {"Data Sources"};
|
||||||
expandNodes(jto, tp);
|
TreePath tp = jto.findPath(nodeNames);
|
||||||
screenshot("Data Sources Tree");
|
expandNodes(jto, tp);
|
||||||
|
} catch (TimeoutExpiredException ex) {
|
||||||
|
screenshot("TimeoutScreenshot");
|
||||||
|
logger.log(Level.SEVERE, "AutopsyTestCases.testNewCaseWizard encountered timed out", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGenerateReportToolbar() {
|
public void testGenerateReportToolbar() {
|
||||||
logger.info("Generate Report Toolbars");
|
try {
|
||||||
MainWindowOperator mwo = MainWindowOperator.getDefault();
|
logger.info("Generate Report Toolbars");
|
||||||
JButtonOperator jbo = new JButtonOperator(mwo, "Generate Report");
|
MainWindowOperator mwo = MainWindowOperator.getDefault();
|
||||||
jbo.pushNoBlock();
|
JButtonOperator jbo = new JButtonOperator(mwo, "Generate Report");
|
||||||
new Timeout("pausing", 5000).sleep();
|
jbo.pushNoBlock();
|
||||||
|
} catch (TimeoutExpiredException ex) {
|
||||||
|
screenshot("TimeoutScreenshot");
|
||||||
|
logger.log(Level.SEVERE, "AutopsyTestCases.testNewCaseWizard encountered timed out", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGenerateReportButton() throws IOException {
|
public void testGenerateReportButton() throws IOException {
|
||||||
logger.info("Generate Report Button");
|
try {
|
||||||
resetTimeouts("ComponentOperator.WaitComponentTimeout", 240000);
|
logger.info("Generate Report Button");
|
||||||
JDialog reportDialog = JDialogOperator.waitJDialog("Generate Report", false, false);
|
setTimeout("ComponentOperator.WaitComponentTimeout", 240000);
|
||||||
JDialogOperator reportDialogOperator = new JDialogOperator(reportDialog);
|
JDialog reportDialog = JDialogOperator.waitJDialog("Generate Report", false, false);
|
||||||
JListOperator listOperator = new JListOperator(reportDialogOperator);
|
JDialogOperator reportDialogOperator = new JDialogOperator(reportDialog);
|
||||||
JButtonOperator jbo0 = new JButtonOperator(reportDialogOperator, "Next");
|
JListOperator listOperator = new JListOperator(reportDialogOperator);
|
||||||
DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss");
|
JButtonOperator jbo0 = new JButtonOperator(reportDialogOperator, "Next");
|
||||||
Date date = new Date();
|
DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss");
|
||||||
String datenotime = dateFormat.format(date);
|
Date date = new Date();
|
||||||
listOperator.clickOnItem(0, 1);
|
String datenotime = dateFormat.format(date);
|
||||||
jbo0.pushNoBlock();
|
listOperator.clickOnItem(0, 1);
|
||||||
new Timeout("pausing", 2000).sleep();
|
jbo0.pushNoBlock();
|
||||||
JButtonOperator jbo1 = new JButtonOperator(reportDialogOperator, "Finish");
|
new Timeout("pausing", 2000).sleep();
|
||||||
jbo1.pushNoBlock();
|
JButtonOperator jbo1 = new JButtonOperator(reportDialogOperator, "Finish");
|
||||||
JDialog previewDialog = JDialogOperator.waitJDialog("Progress", false, false);
|
jbo1.pushNoBlock();
|
||||||
screenshot("Progress");
|
JDialog previewDialog = JDialogOperator.waitJDialog("Progress", false, false);
|
||||||
JDialogOperator previewDialogOperator = new JDialogOperator(previewDialog);
|
JDialogOperator previewDialogOperator = new JDialogOperator(previewDialog);
|
||||||
JLabelOperator.waitJLabel(previewDialog, "Complete", false, false);
|
JLabelOperator.waitJLabel(previewDialog, "Complete", false, false);
|
||||||
JButtonOperator jbo2 = new JButtonOperator(previewDialogOperator, "Close");
|
JButtonOperator jbo2 = new JButtonOperator(previewDialogOperator, "Close");
|
||||||
jbo2.pushNoBlock();
|
jbo2.pushNoBlock();
|
||||||
new Timeout("pausing", 10000).sleep();
|
new Timeout("pausing", 10000).sleep();
|
||||||
System.setProperty("ReportStr", datenotime);
|
System.setProperty("ReportStr", datenotime);
|
||||||
screenshot("Done Testing");
|
} catch (TimeoutExpiredException ex) {
|
||||||
|
screenshot("TimeoutScreenshot");
|
||||||
|
logger.log(Level.SEVERE, "AutopsyTestCases.testNewCaseWizard encountered timed out", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void screenshot(String name) {
|
public void screenshot(String name) {
|
||||||
logger.info("Taking screenshot.");
|
String outPath = getEscapedPath(System.getProperty("out_path"));
|
||||||
try {
|
File screenShotFile = new File(outPath + "\\" + name + ".png");
|
||||||
Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
|
if (!screenShotFile.exists()) {
|
||||||
BufferedImage capture = new Robot().createScreenCapture(screenRect);
|
logger.info("Taking screenshot.");
|
||||||
String outPath = getEscapedPath(System.getProperty("out_path"));
|
try {
|
||||||
ImageIO.write(capture, "png", new File(outPath + "\\" + name + ".png"));
|
Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
|
||||||
new Timeout("pausing", 1000).sleep(); // give it a second to save
|
BufferedImage capture = new Robot().createScreenCapture(screenRect);
|
||||||
} catch (IOException ex) {
|
ImageIO.write(capture, "png", screenShotFile);
|
||||||
logger.log(Level.WARNING, "IOException taking screenshot.", ex);
|
new Timeout("pausing", 1000).sleep(); // give it a second to save
|
||||||
} catch (AWTException ex) {
|
} catch (IOException ex) {
|
||||||
logger.log(Level.WARNING, "AWTException taking screenshot.", ex);
|
logger.log(Level.WARNING, "IOException taking screenshot.", ex);
|
||||||
|
} catch (AWTException ex) {
|
||||||
|
logger.log(Level.WARNING, "AWTException taking screenshot.", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Nightly test failed at WindowWaiter.WaitWindowTimeOut because of TimeoutExpiredException. So we
|
* Nightly test failed at WindowWaiter.WaitWindowTimeOut because of
|
||||||
* use this conveninent method to override the default Jemmy Timeouts value.
|
* TimeoutExpiredException. So we use this conveninent method to override
|
||||||
*/
|
* the default Jemmy Timeouts value.
|
||||||
|
*/
|
||||||
private Timeouts resetTimeouts(String name, int value) {
|
private Timeouts setTimeout(String name, int value) {
|
||||||
Timeouts timeouts = JemmyProperties.getCurrentTimeouts();
|
Timeouts timeouts = JemmyProperties.getCurrentTimeouts();
|
||||||
timeouts.setTimeout(name, value);
|
timeouts.setTimeout(name, value);
|
||||||
return timeouts;
|
return timeouts;
|
||||||
@ -394,7 +459,7 @@ public class AutopsyTestCases {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void expandNodes (JTreeOperator jto, TreePath tp) {
|
private void expandNodes(JTreeOperator jto, TreePath tp) {
|
||||||
try {
|
try {
|
||||||
jto.expandPath(tp);
|
jto.expandPath(tp);
|
||||||
for (TreePath t : jto.getChildPaths(tp)) {
|
for (TreePath t : jto.getChildPaths(tp)) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user