Merge pull request #121 from Devin148/master

Ground-up Report Remake
This commit is contained in:
adam
2012-12-26 06:50:50 -08:00
63 changed files with 4747 additions and 4230 deletions
+12 -17
View File
@@ -198,11 +198,11 @@
<attr name="originalFile" stringvalue="Actions/Tools/org-sleuthkit-autopsy-filesearch-FileSearchAction.instance"/>
<attr name="position" intvalue="200"/>
</file>
<file name="org-sleuthkit-autopsy-report-ReportAction.shadow">
<attr name="originalFile" stringvalue="Actions/Tools/org-sleuthkit-autopsy-report-ReportAction.instance"/>
<file name="org-sleuthkit-autopsy-report-ReportWizardAction.shadow">
<attr name="originalFile" stringvalue="Actions/Tools/org-sleuthkit-autopsy-report-ReportWizardAction.instance"/>
<attr name="position" intvalue="100"/>
</file>
<file name="org-sleuthkit-autopsy-report-ReportAction-separatorAfter.instance">
<file name="org-sleuthkit-autopsy-report-ReportWizardAction-separatorAfter.instance">
<attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
<attr name="position" intvalue="101"/>
</file>
@@ -290,24 +290,19 @@
<attr name="position" intvalue="50"/>
</file>
<file name="org-sleuthkit-autopsy-report-ReportHTML.instance">
<attr name="instanceOf" stringvalue="org.sleuthkit.autopsy.report.ReportModule"/>
<attr name="instanceOf" stringvalue="org.sleuthkit.autopsy.report.TableReportModule"/>
<attr name="instanceCreate" methodvalue="org.sleuthkit.autopsy.report.ReportHTML.getDefault"/>
<attr name="position" intvalue="900"/>
</file>
<file name="org-sleuthkit-autopsy-report-ReportXML.instance">
<attr name="instanceOf" stringvalue="org.sleuthkit.autopsy.report.ReportModule"/>
<attr name="instanceCreate" methodvalue="org.sleuthkit.autopsy.report.ReportXML.getDefault"/>
<file name="org-sleuthkit-autopsy-report-ReportExcel.instance">
<attr name="instanceOf" stringvalue="org.sleuthkit.autopsy.report.TableReportModule"/>
<attr name="instanceCreate" methodvalue="org.sleuthkit.autopsy.report.ReportExcel.getDefault"/>
<attr name="position" intvalue="901"/>
</file>
<file name="org-sleuthkit-autopsy-report-ReportXLS.instance">
<attr name="instanceOf" stringvalue="org.sleuthkit.autopsy.report.ReportModule"/>
<attr name="instanceCreate" methodvalue="org.sleuthkit.autopsy.report.ReportXLS.getDefault"/>
<attr name="position" intvalue="902"/>
</file>
<file name="org-sleuthkit-autopsy-report-ReportBodyFile.instance">
<attr name="instanceOf" stringvalue="org.sleuthkit.autopsy.report.ReportModule"/>
<attr name="instanceOf" stringvalue="org.sleuthkit.autopsy.report.GeneralReportModule"/>
<attr name="instanceCreate" methodvalue="org.sleuthkit.autopsy.report.ReportBodyFile.getDefault"/>
<attr name="position" intvalue="903"/>
<attr name="position" intvalue="902"/>
</file>
<!--<folder name="JavaHelp">
<file name="casemodule-helpset.xml" url="casemodule-helpset.xml">
@@ -355,9 +350,9 @@
<attr name="originalFile" stringvalue="Actions/Tools/org-sleuthkit-autopsy-menuactions-SpacerAction.instance"/>
<attr name="position" intvalue="10000"/>
</file>
<file name="org-sleuthkit-autopsy-report-ReportAction.shadow">
<attr name="displayName" bundlevalue="org.sleuthkit.autopsy.report.Bundle#Toolbars/Reports/org-sleuthkit-autopsy-report-ReportAction.shadow"/>
<attr name="originalFile" stringvalue="Actions/Tools/org-sleuthkit-autopsy-report-ReportAction.instance"/>
<file name="org-sleuthkit-autopsy-report-ReportWizardAction.shadow">
<attr name="displayName" bundlevalue="org.sleuthkit.autopsy.report.Bundle#Toolbars/Reports/org-sleuthkit-autopsy-report-ReportWizardAction.shadow"/>
<attr name="originalFile" stringvalue="Actions/Tools/org-sleuthkit-autopsy-report-ReportWizardAction.instance"/>
<attr name="position" intvalue="102"/>
</file>
</folder>
@@ -18,16 +18,17 @@
*/
package org.sleuthkit.autopsy.datamodel;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
@@ -120,32 +121,35 @@ public class Tags {
/**
* Get a list of all the tag names.
* Uses a custom query for speed when dealing with thousands of Tags.
* @return a list of all tag names.
*/
static String[] getTagNames() {
Set<String> names = new HashSet<String>();
//List<String> names = new ArrayList<String>();
public static List<String> getTagNames() {
Case currentCase = Case.getCurrentCase();
SleuthkitCase skCase = currentCase.getSleuthkitCase();
List<String> names = new ArrayList<String>();
ResultSet rs = null;
try {
Case currentCase = Case.getCurrentCase();
SleuthkitCase skCase = currentCase.getSleuthkitCase();
List<BlackboardArtifact> fileTags = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE);
List<BlackboardArtifact> artifactTags = skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT);
fileTags.addAll(artifactTags);
for(BlackboardArtifact artifact : fileTags) {
List<BlackboardAttribute> attributes = artifact.getAttributes();
for(BlackboardAttribute att : attributes) {
if(att.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TAG_NAME.getTypeID()) {
names.add(att.getValueString());
break;
}
rs = skCase.runQuery("SELECT value_text"
+ " FROM blackboard_attributes"
+ " WHERE attribute_type_id = " + ATTRIBUTE_TYPE.TSK_TAG_NAME.getTypeID()
+ " GROUP BY value_text"
+ " ORDER BY value_text");
while(rs.next()) {
names.add(rs.getString("value_text"));
}
} catch (SQLException ex) {
logger.log(Level.SEVERE, "Failed to query the blackboard for tag names.");
} finally {
if (rs != null) {
try {
skCase.closeRunQuery(rs);
} catch (SQLException ex) {
}
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to get list of artifacts from the case.");
}
return names.toArray(new String[0]);
return names;
}
/**
@@ -153,7 +157,7 @@ public class Tags {
* @param name of the requested tags
* @return a list of all tag artifacts with the given name
*/
static List<BlackboardArtifact> getTagsByName(String name) {
public static List<BlackboardArtifact> getTagsByName(String name) {
try {
Case currentCase = Case.getCurrentCase();
SleuthkitCase skCase = currentCase.getSleuthkitCase();
@@ -0,0 +1,128 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
<Properties>
<Property name="defaultCloseOperation" type="int" value="2"/>
</Properties>
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
</SyntheticProperties>
<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" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="artifactScrollPane" max="32767" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="deselectAllButton" max="32767" attributes="0"/>
<Component id="selectAllButton" max="32767" attributes="0"/>
</Group>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="titleLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="221" max="32767" attributes="0"/>
</Group>
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
<Component id="okButton" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace 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 max="-2" attributes="0"/>
<Component id="titleLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="artifactScrollPane" pref="224" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Component id="selectAllButton" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="deselectAllButton" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace min="-2" pref="11" max="-2" attributes="0"/>
<Component id="okButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="artifactScrollPane">
<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.JList" name="artifactList">
<Properties>
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.editors2.ListModelEditor">
<StringArray count="0"/>
</Property>
<Property name="selectionMode" type="int" value="0"/>
<Property name="layoutOrientation" type="int" value="2"/>
</Properties>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JButton" name="okButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ArtifactSelectionDialog.okButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="okButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="titleLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ArtifactSelectionDialog.titleLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="selectAllButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ArtifactSelectionDialog.selectAllButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="selectAllButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="deselectAllButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ArtifactSelectionDialog.deselectAllButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="deselectAllButtonActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Form>
@@ -0,0 +1,281 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2012 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.report;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
import javax.swing.ListModel;
import javax.swing.event.ListDataListener;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
public class ArtifactSelectionDialog extends javax.swing.JDialog {
private static final Logger logger = Logger.getLogger(ArtifactSelectionDialog.class.getName());
private static ArtifactSelectionDialog instance;
private ArtifactModel model;
private ArtifactRenderer renderer;
private Map<BlackboardArtifact.ARTIFACT_TYPE, Boolean> artifactStates;
private List<BlackboardArtifact.ARTIFACT_TYPE> artifacts;
/**
* Creates new form ArtifactSelectionDialog
*/
public ArtifactSelectionDialog(java.awt.Frame parent, boolean modal) {
super(parent, modal);
initComponents();
populateList();
customInit();
}
/**
* Populate the list of artifacts with all important artifacts.
*/
private void populateList() {
artifacts = getImportantArtifactTypes();
artifactStates = new EnumMap<BlackboardArtifact.ARTIFACT_TYPE, Boolean>(BlackboardArtifact.ARTIFACT_TYPE.class);
for (BlackboardArtifact.ARTIFACT_TYPE type : artifacts) {
artifactStates.put(type, Boolean.TRUE);
}
}
private void customInit() {
model = new ArtifactModel();
renderer = new ArtifactRenderer();
artifactList.setModel(model);
artifactList.setCellRenderer(renderer);
artifactList.setVisibleRowCount(-1);
artifactList.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent evt) {
JList list = (JList) evt.getSource();
int index = list.locationToIndex(evt.getPoint());
BlackboardArtifact.ARTIFACT_TYPE type = (BlackboardArtifact.ARTIFACT_TYPE) model.getElementAt(index);
artifactStates.put(type, !artifactStates.get(type));
list.repaint();
}
});
}
/**
* Returns a list of the artifact types we want to report on.
*/
static List<ARTIFACT_TYPE> getImportantArtifactTypes() {
List<ARTIFACT_TYPE> types = new ArrayList<ARTIFACT_TYPE>();
types.add(ARTIFACT_TYPE.TSK_WEB_BOOKMARK);
types.add(ARTIFACT_TYPE.TSK_WEB_COOKIE);
types.add(ARTIFACT_TYPE.TSK_WEB_HISTORY);
types.add(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD);
types.add(ARTIFACT_TYPE.TSK_RECENT_OBJECT);
types.add(ARTIFACT_TYPE.TSK_INSTALLED_PROG);
types.add(ARTIFACT_TYPE.TSK_KEYWORD_HIT);
types.add(ARTIFACT_TYPE.TSK_HASHSET_HIT);
types.add(ARTIFACT_TYPE.TSK_DEVICE_ATTACHED);
types.add(ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY);
types.add(ARTIFACT_TYPE.TSK_METADATA_EXIF);
types.add(ARTIFACT_TYPE.TSK_TAG_FILE);
types.add(ARTIFACT_TYPE.TSK_TAG_ARTIFACT);
return types;
}
/**
* Display this dialog, and return the selected artifacts.
*/
Map<BlackboardArtifact.ARTIFACT_TYPE, Boolean> display() {
this.setTitle("Advanced Artifact Selection");
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
// set the popUp window / JFrame
int w = this.getSize().width;
int h = this.getSize().height;
// set the location of the popUp Window on the center of the screen
setLocation((screenDimension.width - w) / 2, (screenDimension.height - h) / 2);
this.setVisible(true);
return artifactStates;
}
/**
* 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() {
artifactScrollPane = new javax.swing.JScrollPane();
artifactList = new javax.swing.JList();
okButton = new javax.swing.JButton();
titleLabel = new javax.swing.JLabel();
selectAllButton = new javax.swing.JButton();
deselectAllButton = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
artifactList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
artifactList.setLayoutOrientation(javax.swing.JList.HORIZONTAL_WRAP);
artifactScrollPane.setViewportView(artifactList);
org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(ArtifactSelectionDialog.class, "ArtifactSelectionDialog.okButton.text")); // NOI18N
okButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
okButtonActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(titleLabel, org.openide.util.NbBundle.getMessage(ArtifactSelectionDialog.class, "ArtifactSelectionDialog.titleLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(selectAllButton, org.openide.util.NbBundle.getMessage(ArtifactSelectionDialog.class, "ArtifactSelectionDialog.selectAllButton.text")); // NOI18N
selectAllButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
selectAllButtonActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(deselectAllButton, org.openide.util.NbBundle.getMessage(ArtifactSelectionDialog.class, "ArtifactSelectionDialog.deselectAllButton.text")); // NOI18N
deselectAllButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
deselectAllButtonActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(artifactScrollPane)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(deselectAllButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(selectAllButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addGroup(layout.createSequentialGroup()
.addComponent(titleLabel)
.addGap(0, 221, Short.MAX_VALUE))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(0, 0, Short.MAX_VALUE)
.addComponent(okButton)))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(titleLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(artifactScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 224, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addComponent(selectAllButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(deselectAllButton)
.addGap(0, 0, Short.MAX_VALUE)))
.addGap(11, 11, 11)
.addComponent(okButton)
.addContainerGap())
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
dispose();
}//GEN-LAST:event_okButtonActionPerformed
private void selectAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectAllButtonActionPerformed
for (ARTIFACT_TYPE type : artifacts) {
artifactStates.put(type, Boolean.TRUE);
}
artifactList.repaint();
}//GEN-LAST:event_selectAllButtonActionPerformed
private void deselectAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deselectAllButtonActionPerformed
for (ARTIFACT_TYPE type : artifacts) {
artifactStates.put(type, Boolean.FALSE);
}
artifactList.repaint();
}//GEN-LAST:event_deselectAllButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JList artifactList;
private javax.swing.JScrollPane artifactScrollPane;
private javax.swing.JButton deselectAllButton;
private javax.swing.JButton okButton;
private javax.swing.JButton selectAllButton;
private javax.swing.JLabel titleLabel;
// End of variables declaration//GEN-END:variables
private class ArtifactModel implements ListModel {
@Override
public int getSize() {
return artifacts.size();
}
@Override
public Object getElementAt(int index) {
return artifacts.get(index);
}
@Override
public void addListDataListener(ListDataListener l) {
}
@Override
public void removeListDataListener(ListDataListener l) {
}
}
private class ArtifactRenderer extends JCheckBox implements ListCellRenderer {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
if (value != null) {
BlackboardArtifact.ARTIFACT_TYPE type = (BlackboardArtifact.ARTIFACT_TYPE) value;
setEnabled(list.isEnabled());
setSelected(artifactStates.get(type));
setFont(list.getFont());
setBackground(list.getBackground());
setForeground(list.getForeground());
setText(type.getDisplayName());
return this;
}
return new JLabel();
}
}
}
@@ -1,64 +0,0 @@
/*
*
* Autopsy Forensic Browser
*
* Copyright 2012 Basis Technology Corp.
*
* Copyright 2012 42six Solutions.
* Contact: aebadirad <at> 42six <dot> com
* Project Contact/Architect: 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.report;
import java.lang.reflect.Method;
public class BrowserControl{
/**
* Method to Open the Browser with Given URL
* @param url
*/
public static void openUrl(String url){
String os = System.getProperty("os.name");
Runtime runtime=Runtime.getRuntime();
try{
// Block for Windows Platform
if (os.startsWith("Windows")){
String cmd = "rundll32 url.dll,FileProtocolHandler "+ url;
Process p = runtime.exec(cmd);
}
//Block for Mac OS
else if(os.startsWith("Mac OS")){
Class fileMgr = Class.forName("com.apple.eio.FileManager");
Method openURL = fileMgr.getDeclaredMethod("openURL", new Class[] {String.class});
openURL.invoke(null, new Object[] {url});
}
//Block for UNIX Platform
else {
String[] browsers = {"firefox", "opera", "konqueror", "epiphany", "mozilla", "netscape" };
String browser = null;
for (int count = 0; count < browsers.length && browser == null; count++)
if (runtime.exec(new String[] {"which", browsers[count]}).waitFor() == 0)
browser = browsers[count];
if (browser == null)
throw new Exception("Could not find web browser");
else
runtime.exec(new String[] {browser, url});
}
}catch(Exception x){
System.err.println("Exception occurd while invoking Browser!");
x.printStackTrace();
}
}
}
@@ -1,20 +1,32 @@
OpenIDE-Module-Name=Report
Toolbars/Reports/org-sleuthkit-autopsy-report-ReportAction.shadow=Reports
ReportFilter.progBar.string=
ReportFilter.cancelButton.actionCommand=
ReportFilter.cancelButton.text=Cancel
ReportFilter.jButton1.text=Generate Report
ReportFilter.jButton2.label=
ReportFilter.jButton2.actionCommand=
ReportFilter.jButton2.text=
ReportPanel.saveReport.actionCommand=
ReportPanel.saveReport.text=Export Report...
ReportPanel.jButton1.text=Close
ReportFilter.updateLabel.toolTipText=
ReportFilter.updateLabel.text=
ReportPanel.statusLabel.text=Status Label
ReportPanel.exportButton.text=Save As...
ReportPanel.closeButton.text_1=Close
ReportPanel.reportScrollPane.border.title=Report Summary
ReportPanel.LABEL_LOC.text=Location
ReportPanel.ButtonOpenFolder.text_1=Open Folder
GenerateReportPanel.selectAllLabel.text=Select All
GenerateReportPanel.deselectAllLabel.text=Deselect All
GenerateReportPanel.generateReportButton.text=Generate Report
GenerateReportPanel.advancedButton.text=Advanced
GenerateReportPanel.reportModulesLabel.text=Report Modules:
GenerateReportPanel.dataLabel.text=Select which data to report on:
GenerateReportPanel.artifactsRadioButton.text=All Artifacts
GenerateReportPanel.tagsRadioButton.text=User Tags
ArtifactSelectionDialog.titleLabel.text=Select which artifacts you would like to report on:
ArtifactSelectionDialog.okButton.text=OK
ReportVisualPanel1.reportModulesLabel.text=Report Modules:
DefaultReportConfigurationPanel.infoLabel.text=This report will be configured on the next screen.
ReportVisualPanel2.dataLabel.text=Select which data to report on:
ReportVisualPanel2.deselectAllButton.text=Deselect All
ReportVisualPanel2.selectAllButton.text=Select All
ReportVisualPanel2.advancedButton.text=Advanced
ArtifactSelectionDialog.deselectAllButton.text=Deselect All
ArtifactSelectionDialog.selectAllButton.text=Select All
=Browse...
ReportGenerationPanel.closeButton.text=Close
ReportGenerationPanel.cancelAllButton.text=Cancel All
ReportProgressPanel.reportLabel.text=reportLabel
ReportProgressPanel.pathLabel.text=pathLabel
ReportProgressPanel.separationLabel.text=-
ReportProgressPanel.cancelButton.toolTipText=Queuing
ReportProgressPanel.cancelButton.text=
ReportProgressPanel.processingLabel.text=processingLabel
ReportGenerationPanel.titleLabel.text=Report Generation Progress
ReportVisualPanel2.taggedResultsRadioButton.text=Tagged Results
ReportVisualPanel2.allResultsRadioButton.text=All Results
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.8" 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 max="-2" attributes="0"/>
<Component id="infoLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="infoLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="infoLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="11" style="2"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="DefaultReportConfigurationPanel.infoLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>
@@ -0,0 +1,67 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2012 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.report;
/**
* The panel shown for all TableReportModules when configuring report modules.
*/
public class DefaultReportConfigurationPanel extends javax.swing.JPanel {
/**
* Creates new form DefaultReportConfigurationPanel
*/
public DefaultReportConfigurationPanel() {
initComponents();
}
/**
* 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() {
infoLabel = new javax.swing.JLabel();
infoLabel.setFont(new java.awt.Font("Tahoma", 2, 11)); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(infoLabel, org.openide.util.NbBundle.getMessage(DefaultReportConfigurationPanel.class, "DefaultReportConfigurationPanel.infoLabel.text")); // NOI18N
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(infoLabel)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(infoLabel)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel infoLabel;
// End of variables declaration//GEN-END:variables
}
@@ -0,0 +1,42 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2012 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.report;
import javax.swing.JPanel;
public interface GeneralReportModule extends ReportModule {
/**
* Generate the report and update the report's ProgressPanel, then save the report
* to the reportPath.
*
* @param reportPath path to save the report
* @param progressPanel panel to update the report's progress
*/
public void generateReport(String reportPath, ReportProgressPanel progressPanel);
/**
* Returns the configuration panel for the report, which is displayed in
* the report configuration step of the report wizard.
*
* @return the report's configuration panel
*/
public JPanel getConfigurationPanel();
}
@@ -1,305 +0,0 @@
/*
*
* Autopsy Forensic Browser
*
* Copyright 2012 Basis Technology Corp.
*
* Copyright 2012 42six Solutions.
* Contact: aebadirad <at> 42six <dot> com
* Project Contact/Architect: 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.report;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.SleuthkitCase;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.List;
import org.apache.commons.lang.StringEscapeUtils;
import org.openide.util.Exceptions;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.TskCoreException;
public class Report {
private static final Logger logger = Logger.getLogger(Report.class.getName());
private void Report() {
}
/**
* Returns all the keywords related artifact/attributes and groups them
* based on keyword
*
* @return boolean true if it completes successfully
*
*/
public boolean getGroupedKeywordHit(Writer out) {
HashMap<BlackboardArtifact, ArrayList<BlackboardAttribute>> reportMap = new HashMap<BlackboardArtifact, ArrayList<BlackboardAttribute>>();
Case currentCase = Case.getCurrentCase(); // get the most updated case
SleuthkitCase tempDb = currentCase.getSleuthkitCase();
boolean success = true;
try {
tempDb.copyCaseDB(currentCase.getTempDirectory() + File.separator + "autopsy-copy.db");
SQLiteDBConnect tempdbconnect = new SQLiteDBConnect("org.sqlite.JDBC", "jdbc:sqlite:" + currentCase.getTempDirectory() + File.separator + "autopsy-copy.db");
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_keyword;");
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_preview;");
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_exp;");
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_list;");
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_name;");
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report;");
String temp1 = "CREATE TABLE report_keyword AS SELECT value_text as keyword, blackboard_attributes.attribute_type_id, blackboard_attributes.artifact_id FROM blackboard_attributes WHERE attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID() + ";";
String temp2 = "CREATE TABLE report_preview AS SELECT value_text as preview, blackboard_attributes.attribute_type_id, blackboard_attributes.artifact_id FROM blackboard_attributes WHERE attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW.getTypeID() + ";";
String temp3 = "CREATE TABLE report_exp AS SELECT value_text as exp, blackboard_attributes.attribute_type_id, blackboard_attributes.artifact_id FROM blackboard_attributes WHERE attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP.getTypeID() + ";";
String temp4 = "CREATE TABLE report_list AS SELECT value_text as list, blackboard_attributes.attribute_type_id, blackboard_attributes.artifact_id FROM blackboard_attributes WHERE attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + ";";
String temp5 = "CREATE TABLE report_name AS SELECT name, report_keyword.artifact_id, tsk_files.obj_id as obj_id from tsk_files, blackboard_artifacts, report_keyword WHERE blackboard_artifacts.artifact_id = report_keyword.artifact_id AND blackboard_artifacts.obj_id = tsk_files.obj_id;";
String temp6 = "CREATE TABLE report AS SELECT keyword, preview, exp, list, name, obj_id from report_keyword "
+ "LEFT JOIN report_preview ON report_keyword.artifact_id=report_preview.artifact_id "
+ "LEFT JOIN report_exp ON report_keyword.artifact_id=report_exp.artifact_id "
+ "LEFT JOIN report_list ON report_keyword.artifact_id=report_list.artifact_id "
+ "LEFT JOIN report_name ON report_keyword.artifact_id=report_name.artifact_id;";
tempdbconnect.executeStmt(temp1);
tempdbconnect.executeStmt(temp2);
tempdbconnect.executeStmt(temp3);
tempdbconnect.executeStmt(temp4);
tempdbconnect.executeStmt(temp5);
tempdbconnect.executeStmt(temp6);
ResultSet uniqueresults = tempdbconnect.executeQry("SELECT keyword, exp, preview, list, name, obj_id FROM report ORDER BY keyword ASC");
String keyword = "";
while (uniqueresults.next()) {
if (ReportFilter.cancel == true) { break; }
Long objId = uniqueresults.getLong("obj_id");
AbstractFile file = null;
try {
file = tempDb.getAbstractFileById(objId);
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Could not get AbstractFile from TSK ", ex);
}
StringBuilder table = new StringBuilder();
if (uniqueresults.getString("keyword") == null ? keyword == null : uniqueresults.getString("keyword").equals(keyword)) {
} else {
table.append("</tbody></table><br /><br />\n");
keyword = uniqueresults.getString("keyword");
table.append("<strong>").append(keyword).append("</strong>\n");
table.append("<table><thead><tr><th>").append("File Name").append("</th><th>Preview</th><th>Keyword List</th><th>Path</th></tr><tbody>\n");
}
table.append("<tr><td>").append(uniqueresults.getString("name")).append("</td>\n");
String previewreplace = StringEscapeUtils.escapeHtml(uniqueresults.getString("preview"));
table.append("<td>").append(previewreplace.replaceAll("<!", "")).append("</td>").append("<td>").append(uniqueresults.getString("list")).append("<br />(").append(uniqueresults.getString("exp") == null ? keyword : uniqueresults.getString("exp")).append(")").append("</td>").append("<td>").append(file != null ? file.getUniquePath() : "").append("</td>").append("</tr>\n");
out.write(table.toString());
}
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_keyword;");
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_preview;");
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_exp;");
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_name;");
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_list;");
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report;");
tempdbconnect.closeConnection();
File f1 = new File(currentCase.getTempDirectory() + File.separator + "autopsy-copy.db");
f1.delete();
out.write("</tbody></table><br /><br />");
} catch (IOException ex) {
success = false;
logger.log(Level.SEVERE, "Unable to write to keyword.html file.", ex);
} catch (SQLException ex) {
success = false;
logger.log(Level.SEVERE, "Unable to query databased for keyword hits.", ex);
} catch (Exception ex) {
logger.log(Level.SEVERE, "Failed to connect to database: {0}", ex);
}
return success;
}
/**
* Returns all the hash lookups related artifact/attributes and groups them
* based on hashset name
*
* @return String table is a string of an html table
*
*/
public String getGroupedHashsetHit() {
StringBuilder table = new StringBuilder();
HashMap<BlackboardArtifact, ArrayList<BlackboardAttribute>> reportMap = new HashMap<BlackboardArtifact, ArrayList<BlackboardAttribute>>();
Case currentCase = Case.getCurrentCase(); // get the most updated case
SleuthkitCase tempDb = currentCase.getSleuthkitCase();
try {
tempDb.copyCaseDB(currentCase.getTempDirectory() + File.separator + "autopsy-copy.db");
SQLiteDBConnect tempdbconnect = new SQLiteDBConnect("org.sqlite.JDBC", "jdbc:sqlite:" + currentCase.getTempDirectory() + File.separator + "autopsy-copy.db");
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_hashset;");
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_hashname;");
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_hash;");
String temp1 = "CREATE TABLE report_hashset AS SELECT value_text as hashset,blackboard_attributes.attribute_type_id, blackboard_attributes.artifact_id FROM blackboard_attributes WHERE attribute_type_id = '" + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + "';";
String temp5 = "CREATE TABLE report_hashname AS SELECT name, size, report_hashset.artifact_id from tsk_files,blackboard_artifacts, report_hashset WHERE blackboard_artifacts.artifact_id = report_hashset.artifact_id AND blackboard_artifacts.obj_id = tsk_files.obj_id and blackboard_artifacts.artifact_type_id='" + BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID() + "';";
String temp6 = "CREATE TABLE report_hash AS SELECT hashset,size,name from report_hashset INNER JOIN report_hashname ON report_hashset.artifact_id=report_hashname.artifact_id;";
tempdbconnect.executeStmt(temp1);
tempdbconnect.executeStmt(temp5);
tempdbconnect.executeStmt(temp6);
ResultSet uniqueresults = tempdbconnect.executeQry("SELECT name, size, hashset FROM report_hash ORDER BY hashset ASC");
String keyword = "";
while (uniqueresults.next()) {
if (uniqueresults.getString("hashset") == null ? keyword == null : uniqueresults.getString("hashset").equals(keyword)) {
} else {
table.append("</tbody></table><br /><br />");
keyword = uniqueresults.getString("hashset");
table.append("<strong>").append(keyword).append("</strong>");
table.append("<table><thead><tr><th>").append("File Name").append("</th><th>Size</th></tr><tbody>");
}
table.append("<tr><td>").append(uniqueresults.getString("name")).append("</td>");
table.append("<td>").append(uniqueresults.getString("size")).append("</td>").append("</tr>");
}
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_hashset;");
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_hashname;");
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_hash;");
tempdbconnect.closeConnection();
File f1 = new File(currentCase.getTempDirectory() + File.separator + "autopsy-copy.db");
table.append("</tbody></table><br /><br />");
} catch (SQLException sqle) {
logger.log(Level.SEVERE, "Error ocurred while connecting to database", sqle);
} catch(IOException ioe){
logger.log(Level.SEVERE, "Error ocurred while writing temporary database", ioe);
}catch(Exception e){
logger.log(Level.SEVERE, "Unknown exception occurred", e);
}
return table.toString();
}
/**
* Returns all the hash lookups related artifact/attributes and groups them
* based on hashset name
*
* @return String table is a string of an html table
*
*/
public String getGroupedEmailHit() {
StringBuilder table = new StringBuilder();
HashMap<BlackboardArtifact, ArrayList<BlackboardAttribute>> reportMap = new HashMap<BlackboardArtifact, ArrayList<BlackboardAttribute>>();
Case currentCase = Case.getCurrentCase(); // get the most updated case
SleuthkitCase tempDb = currentCase.getSleuthkitCase();
try {
tempDb.copyCaseDB(currentCase.getTempDirectory() + File.separator + "autopsy-copy.db");
SQLiteDBConnect tempdbconnect = new SQLiteDBConnect("org.sqlite.JDBC", "jdbc:sqlite:" + currentCase.getTempDirectory() + File.separator + "autopsy-copy.db");
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_path;");
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_from;");
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_bcc;");
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_subject;");
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_to;");
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_content;");
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_cc;");
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report_name;");
tempdbconnect.executeStmt("DROP TABLE IF EXISTS report;");
String temp1 = "CREATE TABLE report_path AS SELECT value_text as path,blackboard_attributes.attribute_type_id, blackboard_attributes.artifact_id FROM blackboard_attributes WHERE attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH.getTypeID() + ";";
String temp0 = "CREATE TABLE report_date AS SELECT value_int64 as date, blackboard_attributes.attribute_type_id, blackboard_attributes.artifact_id FROM blackboard_attributes WHERE attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_RCVD.getTypeID() + ";";
String temp2 = "CREATE TABLE report_to AS SELECT value_text as receiver, blackboard_attributes.attribute_type_id, blackboard_attributes.artifact_id FROM blackboard_attributes WHERE attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO.getTypeID() + ";";
String temp3 = "CREATE TABLE report_content AS SELECT value_text as content, blackboard_attributes.attribute_type_id, blackboard_attributes.artifact_id FROM blackboard_attributes WHERE attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN.getTypeID() + ";";
String temp4 = "CREATE TABLE report_cc AS SELECT value_text as cc, blackboard_attributes.attribute_type_id, blackboard_attributes.artifact_id FROM blackboard_attributes WHERE attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CC.getTypeID() + ";";
String temp7 = "CREATE TABLE report_bcc AS SELECT value_text as bcc, blackboard_attributes.attribute_type_id, blackboard_attributes.artifact_id FROM blackboard_attributes WHERE attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_BCC.getTypeID() + ";";
String temp8 = "CREATE TABLE report_author AS SELECT value_text as author, blackboard_attributes.attribute_type_id, blackboard_attributes.artifact_id FROM blackboard_attributes WHERE attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM.getTypeID() + ";";
String temp6 = "CREATE TABLE report_subject AS SELECT value_text as subject, blackboard_attributes.attribute_type_id, blackboard_attributes.artifact_id FROM blackboard_attributes WHERE attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT.getTypeID() + ";";
String temp5 = "CREATE TABLE report_name AS SELECT name, report_path.artifact_id from tsk_files,blackboard_artifacts, report_path WHERE blackboard_artifacts.artifact_id = report_path.artifact_id AND blackboard_artifacts.obj_id = tsk_files.obj_id;";
String temp9 = "CREATE TABLE report AS SELECT path,receiver,content,cc,bcc,subject,name,author,date from report_path INNER JOIN report_to ON report_path.artifact_id=report_to.artifact_id INNER JOIN report_content ON report_to.artifact_id=report_content.artifact_id INNER JOIN report_cc ON report_content.artifact_id=report_cc.artifact_id INNER JOIN report_name ON report_cc.artifact_id=report_name.artifact_id INNER JOIN report_bcc ON report_name.artifact_id=report_bcc.artifact_id INNER JOIN report_subject ON report_bcc.artifact_id=report_subject.artifact_id INNER JOIN report_author ON report_subject.artifact_id=report_author.artifact_id INNER JOIN report_date ON report_author.artifact_id=report_date.artifact_id";
tempdbconnect.executeStmt(temp1);
tempdbconnect.executeStmt(temp0);
tempdbconnect.executeStmt(temp2);
tempdbconnect.executeStmt(temp3);
tempdbconnect.executeStmt(temp4);
tempdbconnect.executeStmt(temp5);
tempdbconnect.executeStmt(temp6);
tempdbconnect.executeStmt(temp7);
tempdbconnect.executeStmt(temp8);
tempdbconnect.executeStmt(temp9);
ResultSet uniqueresults = tempdbconnect.executeQry("SELECT path,receiver,content,cc,bcc,subject,name,author,date FROM report ORDER BY path ASC");
String keyword = "";
while (uniqueresults.next()) {
if (uniqueresults.getString("path") == null ? keyword == null : uniqueresults.getString("path").equals(keyword)) {
} else {
table.append("</tbody></table><br /><br />");
keyword = uniqueresults.getString("path");
table.append("<strong>").append(keyword).append("</strong>");
table.append("<table><thead><tr><th>").append("Folder").append("</th><th>From</th><th>To</th><th>Subject</th><th>Date/Time</th><th>Content</th><th>CC</th><th>BCC</th><th>Path</th></tr><tbody>");
}
table.append("<tr><td>").append(uniqueresults.getString("name")).append("</td>");
table.append("<td>").append(uniqueresults.getString("receiver")).append("</td>").append("<td>").append(uniqueresults.getString("author")).append("</td><td>").append(uniqueresults.getString("subject")).append("</td>");
SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
String value = sdf.format(new java.util.Date(uniqueresults.getLong("date") * 1000));
table.append("<td>").append(value).append("</td>");
table.append("<td>").append(uniqueresults.getString("content")).append("</td>");
table.append("<td>").append(uniqueresults.getString("cc")).append("</td>");
table.append("<td>").append(uniqueresults.getString("bcc")).append("</td>");
table.append("<td>").append(uniqueresults.getString("path")).append("</td>");
table.append("</tr>");
}
tempdbconnect.closeConnection();
File f1 = new File(currentCase.getTempDirectory() + File.separator + "autopsy-copy.db");
boolean success = f1.delete();
table.append("</tbody></table><br /><br />");
} catch (SQLException sqle) {
logger.log(Level.SEVERE, "Error ocurred while connecting to database", sqle);
} catch(IOException ioe){
logger.log(Level.SEVERE, "Error ocurred while writing temporary database", ioe);
}catch(Exception e){
logger.log(Level.SEVERE, "Unknown exception occurred", e);
}
return table.toString();
}
/**
* Returns a hashmap of associated blackboard artifacts/attributes that were
* requested by the config param
*
* @param config is a ReportConfiguration object that has all the types of
* artifacts desired from the blackboard
* @return reportMap a hashmap of all the artifacts for artifact types were
* input
*/
public HashMap<BlackboardArtifact, List<BlackboardAttribute>> getAllTypes(ReportConfiguration config) {
HashMap<BlackboardArtifact, List<BlackboardAttribute>> reportMap = new HashMap<BlackboardArtifact, List<BlackboardAttribute>>();
Case currentCase = Case.getCurrentCase(); // get the most updated case
SleuthkitCase tempDb = currentCase.getSleuthkitCase();
try {
for (Map.Entry<BlackboardArtifact.ARTIFACT_TYPE, Boolean> entry : config.config.entrySet()) {
if (entry.getValue()) {
List<BlackboardArtifact> bbart = tempDb.getBlackboardArtifacts(entry.getKey());
for (BlackboardArtifact artifact : bbart) {
List<BlackboardAttribute> attributes = artifact.getAttributes();
reportMap.put(artifact, attributes);
}
}
}
} catch (TskCoreException tce) {
logger.log(Level.SEVERE, "Error ocurred while connecting to database", tce);
}
return reportMap;
}
}
@@ -1,263 +0,0 @@
/*
*
* Autopsy Forensic Browser
*
* Copyright 2012 Basis Technology Corp.
*
* Copyright 2012 42six Solutions.
* Contact: aebadirad <at> 42six <dot> com
* Project Contact/Architect: 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.report;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.ArrayList;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.*;
import javax.swing.border.Border;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionReferences;
import org.openide.awt.ActionRegistration;
import org.openide.util.HelpCtx;
import org.openide.util.Lookup;
import org.openide.util.NbBundle.Messages;
import org.openide.util.actions.CallableSystemAction;
import org.openide.util.actions.Presenter;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.datamodel.BlackboardArtifact;
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.report.ReportAction")
@ActionRegistration(displayName = "#CTL_ReportAction")
@ActionReferences(value = {
@ActionReference(path = "Menu/Tools", position = 80)})
@Messages(value = "CTL_ReportAction=Run Report")
public final class ReportAction extends CallableSystemAction implements Presenter.Toolbar {
private JButton toolbarButton = new JButton();
private static final String ACTION_NAME = "Generate Report";
static final Logger logger = Logger.getLogger(ReportAction.class.getName());
private JPanel panel;
public static ArrayList<JCheckBox> reportList = new ArrayList<JCheckBox>();
public static ArrayList<String> preview;
public static ReportConfiguration config;
public ReportAction() {
setEnabled(false);
Case.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals(Case.CASE_CURRENT_CASE)) {
Case newCase = (Case) evt.getNewValue();
setEnabled(newCase != null);
//attempt to create a report folder if a case is active
if (newCase != null) {
boolean exists = (new File(newCase.getCaseDirectory() + File.separator + "Reports")).exists();
if (exists) {
// report directory exists -- don't need to do anything
} else {
// report directory does not exist -- create it
boolean reportCreate = (new File(newCase.getCaseDirectory() + File.separator + "Reports")).mkdirs();
if (!reportCreate) {
logger.log(Level.WARNING, "Could not create Reports directory for case. It does not exist.");
}
}
}
}
}
});
// set action of the toolbar button
toolbarButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ReportAction.this.actionPerformed(e);
}
});
}
private class configListener implements ItemListener {
@Override
public void itemStateChanged(ItemEvent e) {
Object source = e.getItem();
JCheckBox comp = (JCheckBox) source;
String name = comp.getName();
BlackboardArtifact.ARTIFACT_TYPE type = BlackboardArtifact.ARTIFACT_TYPE.fromLabel(name);
if (e.getStateChange() == ItemEvent.DESELECTED) {
try {
config.setGenArtifactType(type, Boolean.FALSE);
} catch (ReportModuleException ex) {
}
}
if (e.getStateChange() == ItemEvent.SELECTED) {
try {
config.setGenArtifactType(type, Boolean.TRUE);
} catch (ReportModuleException ex) {
}
}
}
};
@Override
public void actionPerformed(ActionEvent e) {
try {
// create the popUp window for it
final JFrame frame = new JFrame(ACTION_NAME);
final JDialog popUpWindow = new JDialog(frame, ACTION_NAME, true); // to make the popUp Window to be modal
popUpWindow.setLayout(new GridLayout(0, 1));
// initialize panel with loaded settings
final ReportFilter panel = new ReportFilter();
panel.setjButton2ActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
popUpWindow.dispose();
}
});
final configListener clistener = new configListener();
preview = new ArrayList<String>();
reportList.clear();
config = new ReportConfiguration();
int rows = Lookup.getDefault().lookupAll(ReportModule.class).size(); //One row for each report module
final JPanel filterpanel = new JPanel(new GridLayout(rows, 2, 5, 5));
final JPanel artpanel = new JPanel(new GridLayout(0, 3, 0, 0));
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Border border = BorderFactory.createTitledBorder("Reporting Modules");
filterpanel.setBorder(border);
filterpanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
filterpanel.setAlignmentY(Component.TOP_ALIGNMENT);
filterpanel.setAlignmentX(Component.LEFT_ALIGNMENT);
filterpanel.setSize(300, 200);
int placement = 1;
for (ReportModule m : Lookup.getDefault().lookupAll(ReportModule.class)) {
String name = m.getName();
String desc = m.getReportTypeDescription();
JCheckBox ch = new JCheckBox();
ch.setAlignmentY(Component.TOP_ALIGNMENT);
ch.setText(name);
ch.setName(m.getClass().getName());
ch.setToolTipText(desc);
ch.setSelected(false);
if(m.getName().equals(ReportHTML.getDefault().getName())){
ch.setSelected(true);
reportList.add(0, ch);
}
else{
reportList.add(placement++, ch);
}
}
for(int i = reportList.size()-1; i > -1; i--){
filterpanel.add(reportList.get(i), 0);
}
Border artborder = BorderFactory.createTitledBorder("Report Data");
artpanel.setBorder(artborder);
artpanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
artpanel.setAlignmentY(Component.TOP_ALIGNMENT);
artpanel.setAlignmentX(Component.LEFT_ALIGNMENT);
artpanel.setPreferredSize(new Dimension(300, 150));
for (BlackboardArtifact.ARTIFACT_TYPE a : ReportFilter.config.config.keySet()) {
JCheckBox ce = new JCheckBox();
ce.setText(a.getDisplayName());
ce.setToolTipText(a.getDisplayName());
ce.setName(a.getLabel());
ce.setPreferredSize(new Dimension(60, 30));
ce.setSelected(true);
ce.addItemListener(clistener);
artpanel.add(ce);
}
}
});
popUpWindow.add(filterpanel, 0);
popUpWindow.add(artpanel, 1);
// add the panel to the popup window
popUpWindow.add(panel, 2);
popUpWindow.pack();
popUpWindow.setResizable(false);
// Modules need extra room for text to properly show
popUpWindow.setSize(popUpWindow.getWidth(),
popUpWindow.getHeight() + 50);
// set the location of the popUp Window on the center of the screen
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
double w = popUpWindow.getSize().getWidth();
double h = popUpWindow.getSize().getHeight();
popUpWindow.setLocation((int) ((screenDimension.getWidth() - w) / 2), (int) ((screenDimension.getHeight() - h) / 2));
// display the window
popUpWindow.setVisible(true);
// add the command to close the window to the button on the Case Properties form / panel
} catch (Exception ex) {
Logger.getLogger(ReportFilterAction.class.getName()).log(Level.WARNING, "Error displaying " + ACTION_NAME + " window.", ex);
}
}
@Override
public void performAction() {
}
@Override
public String getName() {
return ACTION_NAME;
}
@Override
public HelpCtx getHelpCtx() {
return HelpCtx.DEFAULT_HELP;
}
/**
* Returns the toolbar component of this action
*
* @return component the toolbar button
*/
@Override
public Component getToolbarPresenter() {
ImageIcon icon = new ImageIcon(getClass().getResource("btn_icon_generate_report.png"));
toolbarButton.setIcon(icon);
toolbarButton.setText("Generate Report");
return toolbarButton;
}
/**
* Set this action to be enabled/disabled
*
* @param value whether to enable this action or not
*/
@Override
public void setEnabled(boolean value) {
super.setEnabled(value);
toolbarButton.setEnabled(value);
}
}
@@ -23,43 +23,37 @@
package org.sleuthkit.autopsy.report;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.JPanel;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.report.ReportProgressPanel.ReportStatus;
import org.sleuthkit.datamodel.*;
import org.sleuthkit.datamodel.TskData.TSK_FS_META_MODE_ENUM;
/**
* ReportBodyFile generates a report in the body file format specified on
* The Sleuth Kit wiki as MD5|name|inode|mode_as_string|UID|GID|size|atime|mtime|ctime|crtime.
*/
public class ReportBodyFile implements ReportModule {
//Declare our publically accessible formatted Report, this will change everytime they run a Report
private static String bodyFilePath = "";
private ReportConfiguration config;
private static ReportBodyFile instance = null;
private Case currentCase = Case.getCurrentCase(); // get the current case
private SleuthkitCase skCase = currentCase.getSleuthkitCase();
public class ReportBodyFile implements GeneralReportModule {
private static final Logger logger = Logger.getLogger(ReportBodyFile.class.getName());
private static ReportBodyFile instance = null;
private Case currentCase;
private SleuthkitCase skCase;
private String reportPath;
ReportBodyFile() {
// Hidden constructor for the report
private ReportBodyFile() {
}
// Get the default implementation of this report
public static synchronized ReportBodyFile getDefault() {
if (instance == null) {
instance = new ReportBodyFile();
@@ -68,24 +62,19 @@ public class ReportBodyFile implements ReportModule {
}
/**
* Generates a Body File report in the Reports folder of the current case.
*
* @param reportconfig unused in the body file
* @return the path to the generated report
* @throws ReportModuleException
* Generates a body file format report for use with the MAC time tool.
* @param path path to save the report
* @param progressPanel panel to update the report's progress
*/
@Override
public String generateReport(ReportConfiguration reportconfig) throws ReportModuleException {
config = reportconfig;
// Setup timestamp
DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss");
Date date = new Date();
String datenotime = dateFormat.format(date);
// Get report path
bodyFilePath = currentCase.getCaseDirectory() + File.separator + "Reports" +
File.separator + currentCase.getName() + "-" + datenotime + ".txt";
public void generateReport(String path, ReportProgressPanel progressPanel) {
// Start the progress bar and setup the report
progressPanel.setIndeterminate(false);
progressPanel.start();
progressPanel.updateStatusLabel("Querying files...");
reportPath = path + "BodyFile.txt";
currentCase = Case.getCurrentCase();
skCase = currentCase.getSleuthkitCase();
// Run query to get all files
ResultSet rs = null;
@@ -95,24 +84,36 @@ public class ReportBodyFile implements ReportModule {
+ "WHERE type = '" + TskData.TSK_DB_FILES_TYPE_ENUM.FS.getFileType() + "' "
+ "AND name != '.' "
+ "AND name != '..'");
progressPanel.updateStatusLabel("Loading files...");
List<FsContent> fs = skCase.resultSetToFsContents(rs);
// Check if ingest finished
// Check if ingest has finished
String ingestwarning = "";
if (IngestManager.getDefault().isIngestRunning()) {
ingestwarning = "Warning, this report was run before ingest services completed!\n";
}
// Loop files and write info to report
for (FsContent file : fs) {
if (ReportFilter.cancel == true) {
break;
}
int size = fs.size();
progressPanel.setMaximumProgress(size/100);
BufferedWriter out = null;
try {
// MD5|name|inode|mode_as_string|UID|GID|size|atime|mtime|ctime|crtime
out = new BufferedWriter(new FileWriter(bodyFilePath, true));
out.write(ingestwarning);
BufferedWriter out = null;
try {
// MD5|name|inode|mode_as_string|UID|GID|size|atime|mtime|ctime|crtime
out = new BufferedWriter(new FileWriter(reportPath, true));
out.write(ingestwarning);
// Loop files and write info to report
int count = 0;
for (FsContent file : fs) {
if (progressPanel.getStatus() == ReportStatus.CANCELED) {
break;
}
if(count++ == 100) {
progressPanel.increment();
progressPanel.updateStatusLabel("Now processing " + file.getName() + "...");
count = 0;
}
if(file.getMd5Hash()!=null) {
out.write(file.getMd5Hash());
}
@@ -142,94 +143,42 @@ public class ReportBodyFile implements ReportModule {
out.write("|");
out.write(Long.toString(file.getCrtime()));
out.write("\n");
}
} catch (IOException ex) {
logger.log(Level.WARNING, "Could not write the temp body file report.", ex);
} finally {
try {
out.flush();
out.close();
} catch (IOException ex) {
logger.log(Level.WARNING, "Could not write the temp body file report.", ex);
} finally {
try {
out.flush();
out.close();
} catch (IOException ex) {
logger.log(Level.WARNING, "Could not flush and close the BufferedWriter.", ex);
}
logger.log(Level.WARNING, "Could not flush and close the BufferedWriter.", ex);
}
}
progressPanel.complete();
} catch(SQLException ex) {
logger.log(Level.WARNING, "Failed to get all file information.", ex);
} catch(TskCoreException ex) {
logger.log(Level.WARNING, "Failed to get the unique path.", ex);
} finally {
try {// Close the query
if(rs!=null) { skCase.closeRunQuery(rs); }
if(rs!=null) {
skCase.closeRunQuery(rs);
}
} catch (SQLException ex) {
logger.log(Level.WARNING, "Failed to close the query.", ex);
}
}
return bodyFilePath;
}
@Override
public String getName() {
String name = "Body File (Timeline Report)";
String name = "Body File";
return name;
}
/**
* Save the previously generated report to the given path.
* If the report was not generated in generateReport, save will attempt
* to regenerate it, then copy the file. If the regeneration fails, the
* incident is logged.
*/
@Override
public void save(String path) {
File caseFile = new File(bodyFilePath);
if(!caseFile.exists()) {
logger.log(Level.WARNING, "Body File report does not exist.");
try {
// Try to generate it again
generateReport(config);
logger.log(Level.INFO, "Body File report has been regenerated.");
} catch (ReportModuleException ex) {
logger.log(Level.WARNING, "Failed attempt to regenerate the report.", ex);
}
}
// Check again
if(caseFile.exists()) {
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(caseFile);
out = new FileOutputStream(path);
byte[] b = new byte[Integer.parseInt(Long.toString(caseFile.length()))];
int len = b.length;
int total = 0;
int result = 0;
while ((result = in.read(b, total, len-total)) > 0) {
out.write(b, total, len);
total += result;
}
} catch(FileNotFoundException ex) {
logger.log(Level.WARNING, "Could find the file specified.", ex);
} catch(IOException ex) {
logger.log(Level.WARNING, "Could not read from the FileInputStream.", ex);
} finally {
try {
in.close();
out.flush();
out.close();
} catch (IOException ex) {
logger.log(Level.WARNING, "Could not close and flush the streams.", ex);
}
}
}
// Otherwise give up
}
@Override
public String getReportType() {
String type = "BodyFile";
return type;
public String getFilePath() {
return "BodyFile.txt";
}
@Override
@@ -239,18 +188,13 @@ public class ReportBodyFile implements ReportModule {
}
@Override
public ReportConfiguration GetReportConfiguration() {
return config;
}
@Override
public String getReportTypeDescription() {
String desc = "Body file format report with MAC times for every file, that can be used for a timeline view.";
public String getDescription() {
String desc = "Body file format report with MAC times for every file. This format can be used for a timeline view.";
return desc;
}
@Override
public void getPreview(String path) {
BrowserControl.openUrl(path);
public JPanel getConfigurationPanel() {
return null; // No configuration panel
}
}
@@ -1,141 +0,0 @@
/*
*
* Autopsy Forensic Browser
*
* Copyright 2012 Basis Technology Corp.
*
* Copyright 2012 42six Solutions.
* Contact: aebadirad <at> 42six <dot> com
* Project Contact/Architect: 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.report;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.Map;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.SleuthkitCase;
/**
* Configures which parts of report were requested e.g. based on user input Some
* specialized reporting modules may choose not to generate all requested
* sections and some modules may generate additional, specialized sections
*
*/
public class ReportConfiguration {
//base data structure
Map<BlackboardArtifact.ARTIFACT_TYPE, Boolean> config = new EnumMap<BlackboardArtifact.ARTIFACT_TYPE, Boolean>(BlackboardArtifact.ARTIFACT_TYPE.class);
private final Logger logger = Logger.getLogger(this.getClass().getName());
ReportConfiguration() {
//clear the config just incase before we get the list from the db again
config.clear();
//now lets get the list from the tsk and current case
Case currentCase = Case.getCurrentCase(); // get the most updated case
SleuthkitCase skCase = currentCase.getSleuthkitCase();
try {
ArrayList<BlackboardArtifact.ARTIFACT_TYPE> arttypes = skCase.getBlackboardArtifactTypes();
for (BlackboardArtifact.ARTIFACT_TYPE type : arttypes) {
config.put(type, Boolean.TRUE);
}
} catch (Exception ex) {
logger.log(Level.WARNING, "Error while trying to retrieve list of artifact types from the TSK case .", ex);
}
}
;
/**regets everything that occurs in the constructor normally
*
* @throws ReportModuleException
*/
public void getAllTypes() throws ReportModuleException {
config.clear();
//now lets get the list from the tsk and current case
Case currentCase = Case.getCurrentCase(); // get the most updated case
SleuthkitCase skCase = currentCase.getSleuthkitCase();
try {
ArrayList<BlackboardArtifact.ARTIFACT_TYPE> arttypes = skCase.getBlackboardArtifactTypes();
for (BlackboardArtifact.ARTIFACT_TYPE type : arttypes) {
config.put(type, Boolean.TRUE);
}
} catch (Exception ex) {
logger.log(Level.WARNING, "Error while trying to retrieve list of artifact types from the TSK case .", ex);
}
}
;
/**setters for generally supported report parts
*
*/
public void setGenArtifactType(BlackboardArtifact.ARTIFACT_TYPE type, Boolean value) throws ReportModuleException {
if (config.containsKey(type)) {
config.put(type, value);
} else {
throw new ReportModuleException("The following artifact type is not present:" + type);
}
}
;
/**This allows all that setting to happen in groups
*
*/
public void setGenArtifactType(ArrayList<BlackboardArtifact.ARTIFACT_TYPE> typeList, boolean value) throws ReportModuleException {
for (BlackboardArtifact.ARTIFACT_TYPE type : typeList) {
if (config.containsKey(type)) {
config.put(type, value);
} else {
throw new ReportModuleException("The following artifact type is not present:" + type);
}
}
}
;
/** getters for generally supported report parts
* @param type is a blackboardartifact type
* @return value is the artifact type
*/
public boolean getGenArtifactType(BlackboardArtifact.ARTIFACT_TYPE type) throws ReportModuleException {
boolean value = false;
if (config.containsKey(type)) {
value = config.get(type);
} else {
throw new ReportModuleException("The following artifact type is not present:" + type);
}
return value;
}
public void resetGenArtifactTypes() {
for (Map.Entry<BlackboardArtifact.ARTIFACT_TYPE, Boolean> entry : config.entrySet()) {
config.put(entry.getKey(), Boolean.FALSE);
}
}
}
@@ -0,0 +1,251 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2012 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.report;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Level;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
public class ReportExcel implements TableReportModule {
private static final Logger logger = Logger.getLogger(ReportExcel.class.getName());
private static ReportExcel instance;
private Case currentCase;
private Workbook wb;
private Sheet sheet;
private CellStyle titleStyle;
private CellStyle setStyle;
private CellStyle elementStyle;
private int rowCount = 2;
private Map<String, Integer> dataTypes;
private String currentDataType;
private String reportPath;
// Get the default instance of this report
public static synchronized ReportExcel getDefault() {
if (instance == null) {
instance = new ReportExcel();
}
return instance;
}
// Hidden constructor
private ReportExcel() {
}
/**
* Start the Excel report by creating the Workbook, initializing styles,
* and writing the summary.
* @param path path to save the report
*/
@Override
public void startReport(String path) {
currentCase = Case.getCurrentCase();
wb = new XSSFWorkbook();
titleStyle = wb.createCellStyle();
titleStyle.setBorderBottom((short) 1);
Font titleFont = wb.createFont();
titleFont.setFontHeightInPoints((short) 12);
titleStyle.setFont(titleFont);
setStyle = wb.createCellStyle();
Font setFont = wb.createFont();
setFont.setFontHeightInPoints((short) 14);
setFont.setBoldweight((short) 10);
setStyle.setFont(setFont);
elementStyle = wb.createCellStyle();
elementStyle.setFillBackgroundColor(HSSFColor.LIGHT_YELLOW.index);
Font elementFont = wb.createFont();
elementFont.setFontHeightInPoints((short) 14);
elementStyle.setFont(elementFont);
dataTypes = new TreeMap<String, Integer>();
this.reportPath = path + getFilePath();
// Write the summary
sheet = wb.createSheet("Summary");
sheet.createRow(0).createCell(0).setCellValue("Case Name:");
sheet.getRow(0).createCell(1).setCellValue(currentCase.getName());
sheet.createRow(1).createCell(0).setCellValue("Case Number:");
sheet.getRow(1).createCell(1).setCellValue(currentCase.getNumber());
sheet.createRow(2).createCell(0).setCellValue("Examiner:");
sheet.getRow(2).createCell(1).setCellValue(currentCase.getExaminer());
sheet.createRow(3).createCell(0).setCellValue("# of Images:");
sheet.getRow(3).createCell(1).setCellValue(currentCase.getImageIDs().length);
}
/**
* Write the Workbook to a file and end the report.
*/
@Override
public void endReport() {
FileOutputStream out = null;
try {
out = new FileOutputStream(reportPath);
wb.write(out);
} catch (IOException ex) {
logger.log(Level.SEVERE, "Failed to write Excel report.", ex);
} finally {
if (out != null) {
try {
out.close();
} catch (IOException ex) {
}
}
}
}
/**
* Start a new sheet for the given data type.
* @param title data type name
*/
@Override
public void startDataType(String title) {
sheet = wb.createSheet(title);
sheet.setAutobreaks(true);
currentDataType = title;
}
/**
* End the current data type and sheet.
*/
@Override
public void endDataType() {
Row temp = sheet.createRow(0);
temp.createCell(0).setCellValue("Number of " + currentDataType + " artifacts:");
temp.createCell(1).setCellValue(rowCount);
dataTypes.put(currentDataType, rowCount);
rowCount = 2;
}
/**
* Start a new set for the current data type.
* @param setName name of the set
*/
@Override
public void startSet(String setName) {
Row temp = sheet.createRow(rowCount);
temp.setRowStyle(setStyle);
temp.createCell(0).setCellValue(setName);
rowCount++;
}
/**
* End the current set.
*/
@Override
public void endSet() {
rowCount++; // Put a space between the sets
}
// Ignored in Excel Report
@Override
public void addSetIndex(List<String> sets) {
}
/**
* Add an element to the set
* @param elementName element name
*/
@Override
public void addSetElement(String elementName) {
Row temp = sheet.createRow(rowCount);
temp.setRowStyle(elementStyle);
temp.createCell(0).setCellValue(elementName);
rowCount++;
}
/**
* Label the top of this sheet with the table column names.
* @param titles column names
*/
@Override
public void startTable(List<String> titles) {
Row temp = sheet.createRow(rowCount);
temp.setRowStyle(titleStyle);
for (int i=0; i<titles.size(); i++) {
temp.createCell(i).setCellValue(titles.get(i));
}
rowCount++;
}
// Do nothing on end table
@Override
public void endTable() {
}
/**
* Add a row of information to the report.
* @param row cells to add
*/
@Override
public void addRow(List<String> row) {
Row temp = sheet.createRow(rowCount);
for (int i=0; i<row.size(); i++) {
temp.createCell(i).setCellValue(row.get(i));
}
rowCount++;
}
/**
* Return the given long date as a String.
* @param date as a long
* @return String date
*/
@Override
public String dateToString(long date) {
SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
return sdf.format(new java.util.Date(date * 1000));
}
@Override
public String getName() {
return "Excel";
}
@Override
public String getDescription() {
return "An XLS formatted report which is meant to be viewed in Excel.";
}
@Override
public String getExtension() {
return ".xlsx";
}
@Override
public String getFilePath() {
return "Excel.xlsx";
}
}
@@ -1,135 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<NonVisualComponents>
<Component class="javax.swing.JButton" name="jButton2">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportFilter.jButton2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="actionCommand" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportFilter.jButton2.actionCommand" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="label" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportFilter.jButton2.label" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</NonVisualComponents>
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[500, 75]"/>
</Property>
</Properties>
<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="false"/>
<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 max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="updateLabel" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="jButton1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Component id="progBar" pref="395" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="cancelButton" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace min="-2" pref="24" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="19" max="-2" attributes="0"/>
<Component id="jButton1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="cancelButton" max="32767" attributes="0"/>
<Component id="progBar" min="-2" pref="23" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="updateLabel" min="-2" pref="11" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JProgressBar" name="progBar">
<Properties>
<Property name="doubleBuffered" type="boolean" value="true"/>
<Property name="enabled" type="boolean" value="false"/>
<Property name="name" type="java.lang.String" value="" noResource="true"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[146, 15]"/>
</Property>
<Property name="string" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportFilter.progBar.string" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="stringPainted" type="boolean" value="true"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="jButton1">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportFilter.jButton1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="mouseReleased" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="jButton1MouseReleased"/>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButton1ActionPerformed"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_SerializeTo" type="java.lang.String" value="reportFilter_jButton1"/>
</AuxValues>
</Component>
<Component class="javax.swing.JButton" name="cancelButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportFilter.cancelButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="actionCommand" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportFilter.cancelButton.actionCommand" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="updateLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportFilter.updateLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportFilter.updateLabel.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>
@@ -1,289 +0,0 @@
/*
*
* Autopsy Forensic Browser
*
* Copyright 2012 Basis Technology Corp.
*
* Copyright 2012 42six Solutions.
* Contact: aebadirad <at> 42six <dot> com
* Project Contact/Architect: 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.report;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.*;
import javax.swing.border.Border;
import org.openide.util.Lookup;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.SleuthkitCase;
/**
*
* @author Alex
*/
public class ReportFilter extends javax.swing.JPanel {
public static ArrayList<Integer> filters = new ArrayList<Integer>();
public static ReportConfiguration config = new ReportConfiguration();
private final Logger logger = Logger.getLogger(this.getClass().getName());
public final ReportFilter panel = this;
ReportPanelAction rpa = new ReportPanelAction();
public static boolean cancel = false;
Case currentCase = Case.getCurrentCase(); // get the most updated case
SleuthkitCase skCase = currentCase.getSleuthkitCase();
/**
* Creates new form ReportFilter
*/
public ReportFilter() {
this.setLayout(new GridLayout(0, 1));
initComponents();
cancel = false;
try {
config.getAllTypes();
} catch (ReportModuleException ex) {
Logger.getLogger(Report.class.getName()).log(Level.WARNING, "Exception occurred", ex);
}
}
/**
* 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() {
jButton2 = new javax.swing.JButton();
progBar = new javax.swing.JProgressBar();
jButton1 = new javax.swing.JButton();
cancelButton = new javax.swing.JButton();
updateLabel = new javax.swing.JLabel();
jButton2.setText(org.openide.util.NbBundle.getMessage(ReportFilter.class, "ReportFilter.jButton2.text")); // NOI18N
jButton2.setActionCommand(org.openide.util.NbBundle.getMessage(ReportFilter.class, "ReportFilter.jButton2.actionCommand")); // NOI18N
jButton2.setLabel(org.openide.util.NbBundle.getMessage(ReportFilter.class, "ReportFilter.jButton2.label")); // NOI18N
setPreferredSize(new java.awt.Dimension(500, 75));
progBar.setDoubleBuffered(true);
progBar.setEnabled(false);
progBar.setName(""); // NOI18N
progBar.setPreferredSize(new java.awt.Dimension(146, 15));
progBar.setString(org.openide.util.NbBundle.getMessage(ReportFilter.class, "ReportFilter.progBar.string")); // NOI18N
progBar.setStringPainted(true);
jButton1.setText(org.openide.util.NbBundle.getMessage(ReportFilter.class, "ReportFilter.jButton1.text")); // NOI18N
jButton1.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseReleased(java.awt.event.MouseEvent evt) {
jButton1MouseReleased(evt);
}
});
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
cancelButton.setText(org.openide.util.NbBundle.getMessage(ReportFilter.class, "ReportFilter.cancelButton.text")); // NOI18N
cancelButton.setActionCommand(org.openide.util.NbBundle.getMessage(ReportFilter.class, "ReportFilter.cancelButton.actionCommand")); // NOI18N
cancelButton.setEnabled(false);
cancelButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cancelButtonActionPerformed(evt);
}
});
updateLabel.setText(org.openide.util.NbBundle.getMessage(ReportFilter.class, "ReportFilter.updateLabel.text")); // NOI18N
updateLabel.setToolTipText(org.openide.util.NbBundle.getMessage(ReportFilter.class, "ReportFilter.updateLabel.toolTipText")); // NOI18N
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()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(updateLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addContainerGap())
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jButton1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addGroup(layout.createSequentialGroup()
.addComponent(progBar, javax.swing.GroupLayout.DEFAULT_SIZE, 395, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cancelButton)))
.addGap(24, 24, 24))))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(19, 19, 19)
.addComponent(jButton1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(cancelButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(progBar, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(updateLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 11, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
}// </editor-fold>//GEN-END:initComponents
public void getfilters(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
jButton1.setEnabled(false);
progBar.setEnabled(true);
cancelButton.setEnabled(true);
progBar.setStringPainted(true);
progBar.setValue(0);
ReportConfiguration newConfig = ReportAction.config;
ArrayList<String> preview = ReportAction.preview;
ArrayList<JCheckBox> reportList = ReportAction.reportList;
ArrayList<String> classList = new ArrayList<String>();
for (JCheckBox box : reportList) {
if (box.isSelected()) {
classList.add(box.getName());
}
}
config.resetGenArtifactTypes();
getReports(newConfig, classList, preview);
}//GEN-LAST:event_jButton1ActionPerformed
public void getReports(final ReportConfiguration reportConfig, final ArrayList<String> classList, final ArrayList<String> preview) {
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
rpa.reportGenerate(reportConfig, classList, preview, panel);
return null;
}
;
// this is called when the SwingWorker's doInBackground finishes
@Override
protected void done() {
progBar.setVisible(false); // hide my progress bar JFrame
}
;
}.execute();
progBar.setVisible(true);
}
private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
cancelButton.setText("Cancelled!");
cancel = true;
}//GEN-LAST:event_cancelButtonActionPerformed
private void jButton1MouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jButton1MouseReleased
}//GEN-LAST:event_jButton1MouseReleased
public void progBarSet(int cc) {
final int count = cc;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
int start = progBar.getValue();
int end = start + count;
progBar.setValue(end);
progBar.setString(null);
progBar.setString(progBar.getString());
progBar.setStringPainted(true);
if (progBar.getPercentComplete() == 1.0) {
progBar.setString("Populating Report - Please wait...");
progBar.setStringPainted(true);
progBar.setIndeterminate(true);
}
}
});
}
public void progBarDone() {
int max = progBar.getMaximum();
progBar.setValue(max);
jButton2.doClick();
}
public void progBarStartText() {
progBar.setIndeterminate(true);
progBar.setString("Querying Database for Report Results...");
}
public void setUpdateLabel(final String text) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
updateLabel.setText(text);
updateLabel.repaint();
}
});
}
public void progBarText() {
progBar.setString("Populating Report - Please wait...");
progBar.setStringPainted(true);
progBar.repaint();
progBar.setIndeterminate(true);
}
public void progBarCount(int count) {
progBar.setIndeterminate(false);
progBar.setString(null);
progBar.setMinimum(0);
progBar.setMaximum(count);
progBar.setValue(0);
//Double bper = progBar.getPercentComplete();
progBar.setString(progBar.getString());
}
public void setjButton1ActionListener(ActionListener e) {
jButton1.addActionListener(e);
}
public void setjButton2ActionListener(ActionListener e) {
jButton2.addActionListener(e);
cancelButton.addActionListener(e);
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton cancelButton;
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JProgressBar progBar;
private javax.swing.JLabel updateLabel;
// End of variables declaration//GEN-END:variables
}
@@ -1,84 +0,0 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2012 Basis Technology Corp.
*
* Copyright 2011 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.report;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.util.logging.Level;
import javax.swing.JDialog;
import javax.swing.JFrame;
import org.openide.util.HelpCtx;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* The ReportFilterAction opens the reportFilterPanel in a dialog, and saves the
* settings of the panel if the Apply button is clicked.
*
* @author pmartel
*/
class ReportFilterAction {
private static final String ACTION_NAME = "Report Window";
//@Override
public void performAction() {
Logger.noteAction(this.getClass());
try {
// create the popUp window for it
Container cpane;
final JFrame frame = new JFrame(ACTION_NAME);
final JDialog popUpWindow = new JDialog(frame, ACTION_NAME, true); // to make the popUp Window to be modal
cpane = frame.getContentPane();
// initialize panel with loaded settings
final ReportFilter panel = new ReportFilter();
// add the panel to the popup window
popUpWindow.add(panel);
popUpWindow.pack();
popUpWindow.setResizable(false);
// set the location of the popUp Window on the center of the screen
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
double w = popUpWindow.getSize().getWidth();
double h = popUpWindow.getSize().getHeight();
popUpWindow.setLocation((int) ((screenDimension.getWidth() - w) / 2), (int) ((screenDimension.getHeight() - h) / 2));
// display the window
popUpWindow.setVisible(true);
} catch (Exception ex) {
Logger.getLogger(ReportFilterAction.class.getName()).log(Level.WARNING, "Error displaying " + ACTION_NAME + " window.", ex);
}
}
//@Override
public String getName() {
return ACTION_NAME;
}
// @Override
public HelpCtx getHelpCtx() {
return HelpCtx.DEFAULT_HELP;
}
}
@@ -1,55 +0,0 @@
/*
*
* Autopsy Forensic Browser
*
* Copyright 2012 Basis Technology Corp.
*
* Copyright 2012 42six Solutions.
* Contact: aebadirad <at> 42six <dot> com
* Project Contact/Architect: 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.report;
import java.util.HashMap;
import java.util.List;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
/**
*
* This class is the 'default' way to get artifacts/attributes from the
* blackboard using a reportconfiguration object.
*/
public class ReportGen {
private HashMap<BlackboardArtifact, List<BlackboardAttribute>> results = new HashMap<BlackboardArtifact, List<BlackboardAttribute>>();
ReportGen() {
}
HashMap<BlackboardArtifact, List<BlackboardAttribute>> getResults() {
return results;
}
public void clearReport() {
results.clear();
}
public void populateReport(ReportConfiguration config) {
clearReport();
Report bbreport = new Report();
results = bbreport.getAllTypes(config);
}
}
@@ -1,6 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[700, 400]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
@@ -16,20 +21,19 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="optionSeparator" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="reportScrollPane" alignment="0" pref="404" max="32767" attributes="0"/>
<Component id="statusLabel" alignment="1" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Component id="LABEL_LOC" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Component id="reportScrollPane" max="32767" attributes="0"/>
<Component id="titleSeparator" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="titleLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="522" max="32767" attributes="0"/>
</Group>
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
<Component id="exportButton" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="ButtonOpenFolder" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="380" max="32767" attributes="0"/>
<Component id="cancelAllButton" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="closeButton" min="-2" max="-2" attributes="0"/>
</Group>
@@ -42,93 +46,103 @@
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="reportScrollPane" min="-2" pref="125" max="-2" attributes="0"/>
<Component id="titleLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Component id="titleSeparator" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="statusLabel" min="-2" max="-2" attributes="0"/>
<Component id="reportScrollPane" pref="290" max="32767" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="optionSeparator" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="LABEL_LOC" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="closeButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="exportButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="ButtonOpenFolder" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="cancelAllButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JButton" name="closeButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportGenerationPanel.closeButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="closeButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="cancelAllButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportGenerationPanel.cancelAllButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelAllButtonActionPerformed"/>
</Events>
</Component>
<Container class="javax.swing.JScrollPane" name="reportScrollPane">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="Report Summary">
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportPanel.reportScrollPane.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</TitledBorder>
<Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo">
<LineBorder>
<Color PropertyName="color" blue="b4" green="b4" id="Active Caption Border" palette="2" red="b4" type="palette"/>
</LineBorder>
</Border>
</Property>
<Property name="verticalScrollBarPolicy" type="int" value="22"/>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="reportSummaryPanel">
<Container class="javax.swing.JPanel" name="reportPanel">
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[600, 400]"/>
</Property>
</Properties>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="675" max="32767" attributes="0"/>
<EmptySpace min="0" pref="661" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="214" max="32767" attributes="0"/>
<EmptySpace min="0" pref="400" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
</Container>
</SubComponents>
</Container>
<Component class="javax.swing.JButton" name="closeButton">
<Component class="javax.swing.JLabel" name="titleLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="11" style="1"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportPanel.closeButton.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportGenerationPanel.titleLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="exportButton">
<Component class="javax.swing.JSeparator" name="titleSeparator">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportPanel.exportButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="exportButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="statusLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportPanel.statusLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="0" green="0" red="0" type="rgb"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="LABEL_LOC">
<Component class="javax.swing.JSeparator" name="optionSeparator">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportPanel.LABEL_LOC.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="0" green="0" red="0" type="rgb"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="ButtonOpenFolder">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportPanel.ButtonOpenFolder.text_1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="ButtonOpenFolderActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Form>
@@ -0,0 +1,237 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2012 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.report;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Box;
import javax.swing.JOptionPane;
import org.sleuthkit.autopsy.report.ReportProgressPanel.ReportStatus;
public class ReportGenerationPanel extends javax.swing.JPanel {
private GridBagConstraints c;
private List<ReportProgressPanel> progressPanels;
private Component glue;
private ActionListener actionListener;
/**
* Creates new form ReportGenerationPanel
*/
public ReportGenerationPanel() {
initComponents();
customInit();
}
private void customInit() {
reportPanel.setLayout(new GridBagLayout());
progressPanels = new ArrayList<ReportProgressPanel>();
c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.gridx = 0;
c.gridy = 0;
c.weightx = 1.0;
glue = Box.createVerticalGlue();
}
/**
* Add a ReportProgressPanel to this panel with the given report name and path.
*
* @param reportName report name
* @param reportPath report path
* @return ReportProgressPanel progress panel to update
*/
public ReportProgressPanel addReport(String reportName, String reportPath) {
// Remove the glue
reportPanel.remove(glue);
// Add the new panel
ReportProgressPanel panel = new ReportProgressPanel(reportName, reportPath);
progressPanels.add(panel);
c.weighty = 0.0;
c.anchor = GridBagConstraints.NORTH;
reportPanel.add(panel, c);
c.gridy++;
// Add the glue back to the bottom
c.weighty = 1.0;
c.anchor = GridBagConstraints.PAGE_END;
reportPanel.add(glue, c);
reportPanel.setPreferredSize(new Dimension(600, progressPanels.size() * 80));
reportPanel.repaint();
return panel;
}
/**
* Close this panel and it's dialog if all reports are done.
*/
void close() {
boolean closeable = true;
for (ReportProgressPanel panel : progressPanels) {
if (panel.getStatus() != ReportStatus.CANCELED && panel.getStatus() != ReportStatus.COMPLETE) {
closeable = false;
}
}
if (closeable) {
actionListener.actionPerformed(null);
} else {
int result = JOptionPane.showConfirmDialog(null, "Are you sure you'd like to close the dialog?\nAll reports will be canceled.", "Closing", JOptionPane.YES_NO_OPTION);
if (result == 0) {
cancelAllReports();
actionListener.actionPerformed(null);
}
}
}
/**
* Cancel all reports.
*/
private void cancelAllReports() {
for (ReportProgressPanel panel : progressPanels) {
panel.cancel();
}
}
/**
* 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() {
closeButton = new javax.swing.JButton();
cancelAllButton = new javax.swing.JButton();
reportScrollPane = new javax.swing.JScrollPane();
reportPanel = new javax.swing.JPanel();
titleLabel = new javax.swing.JLabel();
titleSeparator = new javax.swing.JSeparator();
optionSeparator = new javax.swing.JSeparator();
setPreferredSize(new java.awt.Dimension(700, 400));
org.openide.awt.Mnemonics.setLocalizedText(closeButton, org.openide.util.NbBundle.getMessage(ReportGenerationPanel.class, "ReportGenerationPanel.closeButton.text")); // NOI18N
closeButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
closeButtonActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(cancelAllButton, org.openide.util.NbBundle.getMessage(ReportGenerationPanel.class, "ReportGenerationPanel.cancelAllButton.text")); // NOI18N
cancelAllButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cancelAllButtonActionPerformed(evt);
}
});
reportScrollPane.setBorder(javax.swing.BorderFactory.createLineBorder(java.awt.SystemColor.activeCaptionBorder));
reportScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
reportPanel.setPreferredSize(new java.awt.Dimension(600, 400));
javax.swing.GroupLayout reportPanelLayout = new javax.swing.GroupLayout(reportPanel);
reportPanel.setLayout(reportPanelLayout);
reportPanelLayout.setHorizontalGroup(
reportPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 661, Short.MAX_VALUE)
);
reportPanelLayout.setVerticalGroup(
reportPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE)
);
reportScrollPane.setViewportView(reportPanel);
titleLabel.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(titleLabel, org.openide.util.NbBundle.getMessage(ReportGenerationPanel.class, "ReportGenerationPanel.titleLabel.text")); // NOI18N
titleSeparator.setForeground(new java.awt.Color(0, 0, 0));
optionSeparator.setForeground(new java.awt.Color(0, 0, 0));
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(optionSeparator)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(reportScrollPane)
.addComponent(titleSeparator, javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
.addComponent(titleLabel)
.addGap(0, 522, Short.MAX_VALUE))
.addGroup(layout.createSequentialGroup()
.addGap(0, 380, Short.MAX_VALUE)
.addComponent(cancelAllButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(closeButton)))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(titleLabel)
.addGap(0, 0, 0)
.addComponent(titleSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(reportScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 290, Short.MAX_VALUE)
.addGap(18, 18, 18)
.addComponent(optionSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(closeButton)
.addComponent(cancelAllButton))
.addContainerGap())
);
}// </editor-fold>//GEN-END:initComponents
private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeButtonActionPerformed
close();
}//GEN-LAST:event_closeButtonActionPerformed
private void cancelAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelAllButtonActionPerformed
int result = JOptionPane.showConfirmDialog(null, "Are you sure you'd like to cancel all the reports?", "Cancel All", JOptionPane.YES_NO_OPTION);
if (result == 0) {
cancelAllReports();
}
}//GEN-LAST:event_cancelAllButtonActionPerformed
void addCloseAction(ActionListener l) {
this.actionListener = l;
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton cancelAllButton;
private javax.swing.JButton closeButton;
private javax.swing.JSeparator optionSeparator;
private javax.swing.JPanel reportPanel;
private javax.swing.JScrollPane reportScrollPane;
private javax.swing.JLabel titleLabel;
private javax.swing.JSeparator titleSeparator;
// End of variables declaration//GEN-END:variables
}
@@ -0,0 +1,950 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2012 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.report;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Level;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.SwingWorker;
import org.openide.filesystems.FileUtil;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.EscapeUtil;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.Tags;
import org.sleuthkit.autopsy.report.ReportProgressPanel.ReportStatus;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
/**
* Generates all TableReportModules and GeneralReportModules, given whether each module for both
* types is enabled or disabled, and the base report path to save them at.
*
* After creating an instance of ReportGenerator, one must tell it which reports to run,
* TableReportModules on Tags or Artifacts, and the GeneralReportModules.
* Then, one calls displayProgressPanels() to display the progress to the user.
*/
public class ReportGenerator {
private static final Logger logger = Logger.getLogger(ReportGenerator.class.getName());
private Case currentCase = Case.getCurrentCase();
private SleuthkitCase skCase = currentCase.getSleuthkitCase();
private Map<TableReportModule, ReportProgressPanel> tableProgress;
private Map<GeneralReportModule, ReportProgressPanel> generalProgress;
private String reportPath;
private ReportGenerationPanel panel = new ReportGenerationPanel();
ReportGenerator(Map<TableReportModule, Boolean> tableModuleStates, Map<GeneralReportModule, Boolean> generalModuleStates) {
// Setup the reporting directory to be [CASE DIRECTORY]/Reports/[Case name] [Timestamp]/
DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss");
Date date = new Date();
String datenotime = dateFormat.format(date);
this.reportPath = currentCase.getCaseDirectory() + File.separator + "Reports" + File.separator + currentCase.getName() + " " + datenotime + File.separator;
// Create the reporting directory
try {
FileUtil.createFolder(new File(this.reportPath));
} catch (IOException ex) {
logger.log(Level.SEVERE, "Failed to make report folder, may be unable to generate reports.", ex);
}
// Initialize the progress panels
generalProgress = new HashMap<GeneralReportModule, ReportProgressPanel>();
tableProgress = new HashMap<TableReportModule, ReportProgressPanel>();
setupProgressPanels(tableModuleStates, generalModuleStates);
}
/**
* For every ReportModule which the user enabled, create a ReportProgressPanel for that report.
*
* @param tableModuleStates the enabled/disabled state of each TableReportModule
* @param generalModuleStates the enabled/disabled state of each GeneralReportModule
*/
private void setupProgressPanels(Map<TableReportModule, Boolean> tableModuleStates, Map<GeneralReportModule, Boolean> generalModuleStates) {
for (Entry<TableReportModule, Boolean> entry : tableModuleStates.entrySet()) {
if (entry.getValue()) {
TableReportModule module = entry.getKey();
tableProgress.put(module, panel.addReport(module.getName(), reportPath + module.getFilePath()));
}
}
for (Entry<GeneralReportModule, Boolean> entry : generalModuleStates.entrySet()) {
if (entry.getValue()) {
GeneralReportModule module = entry.getKey();
generalProgress.put(module, panel.addReport(module.getName(), reportPath + module.getFilePath()));
}
}
}
/**
* Display the progress panels to the user, and add actions to close the parent dialog.
*/
public void displayProgressPanels() {
final JDialog dialog = new JDialog(new JFrame(), true);
dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
dialog.setTitle("Report Generation Progress...");
dialog.add(this.panel);
dialog.pack();
panel.addCloseAction(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
dialog.dispose();
}
});
dialog.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
panel.close();
}
});
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
int w = dialog.getSize().width;
int h = dialog.getSize().height;
// set the location of the popUp Window on the center of the screen
dialog.setLocation((screenDimension.width - w) / 2, (screenDimension.height - h) / 2);
dialog.setVisible(true);
}
/**
* Generate the GeneralReportModule reports in a new SwingWorker.
*/
public void generateGeneralReports() {
GeneralWorker worker = new GeneralWorker();
worker.execute();
}
/**
* Generate the TableReportModule reports on Blackboard Artifacts in a new SwingWorker.
*
* @param artifactStates the enabled/disabled state of all artifacts
*/
public void generateTableArtifactReport(Map<ARTIFACT_TYPE, Boolean> artifactStates) {
ArtifactWorker worker = new ArtifactWorker(artifactStates);
worker.execute();
}
/**
* Generate the TableReportModule reports on Tags in a new SwingWorker.
*
* @param tagStates the enabled/disabled state of all tags
*/
public void generateTableTagReport(Map<String, Boolean> tagStates) {
TagWorker worker = new TagWorker(tagStates);
worker.execute();
}
/**
* SwingWorker to generate a report on all GeneralReportModules.
*/
private class GeneralWorker extends SwingWorker<Integer, Integer> {
@Override
protected Integer doInBackground() throws Exception {
for (Entry<GeneralReportModule, ReportProgressPanel> entry : generalProgress.entrySet()) {
GeneralReportModule module = entry.getKey();
if (generalProgress.get(module).getStatus() != ReportStatus.CANCELED) {
module.generateReport(reportPath, generalProgress.get(module));
}
}
return 0;
}
}
/**
* SwingWorker to generate a report on Tags for all TableReportModules.
*/
private class TagWorker extends SwingWorker<Integer, Integer> {
List<TableReportModule> tableModules;
List<String> tags;
// Create a new TagWorker with the enabled/diabled state of each Tag
TagWorker(Map<String, Boolean> tagStates) {
tableModules = new ArrayList<TableReportModule>();
for (Entry<TableReportModule, ReportProgressPanel> entry : tableProgress.entrySet()) {
tableModules.add(entry.getKey());
}
tags = new ArrayList<String>();
for (Entry<String, Boolean> entry : tagStates.entrySet()) {
if (entry.getValue()) {
tags.add(entry.getKey());
}
}
}
@Override
protected Integer doInBackground() throws Exception {
// For each module, start the report
for (TableReportModule module : tableModules) {
ReportProgressPanel progress = tableProgress.get(module);
if (progress.getStatus() != ReportStatus.CANCELED) {
module.startReport(reportPath);
progress.start();
progress.setIndeterminate(false);
progress.setMaximumProgress(tags.size());
}
}
// For every tag in tagStates
for (String tag : tags) {
// Check to see if all the TableReportModules have been canceled
if (tableModules.isEmpty()) {
break;
}
Iterator<TableReportModule> iter = tableModules.iterator();
while (iter.hasNext()) {
TableReportModule module = iter.next();
if (tableProgress.get(module).getStatus() == ReportStatus.CANCELED) {
iter.remove();
}
}
// Start a datatype for this tag
for (TableReportModule module : tableModules) {
tableProgress.get(module).updateStatusLabel("Now processing " + tag + "...");
module.startDataType(tag);
module.startTable(new ArrayList<String>(Arrays.asList(new String[] {"Comment", "File Name", "File Path"})));
}
// For every artifact with this tag name, add a row
for (BlackboardArtifact artifact : Tags.getTagsByName(tag)) {
for (TableReportModule module : tableModules) {
try {
Map<Integer, String> attributes = getMappedAttributes(skCase.getBlackboardAttributes(artifact), module);
List<String> row = new ArrayList<String>();
row.add(attributes.get(ATTRIBUTE_TYPE.TSK_COMMENT.getTypeID()));
AbstractFile file = getAbstractFile(artifact.getObjectID());
if(file != null) {
row.add(file.getName());
row.add(file.getUniquePath());
} else {
row.add("");
row.add("");
}
module.addRow(row);
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to get Tag information from Blackboard.", ex);
}
}
}
// Finish up this data type
for (TableReportModule module : tableModules) {
tableProgress.get(module).increment();
module.endTable();
module.endDataType();
}
}
// End the report
for (TableReportModule module : tableModules) {
tableProgress.get(module).complete();
module.endReport();
}
return 0;
}
}
/**
* SwingWorker to generate a report on Blackboard Artifacts for all TableReportModules.
*/
private class ArtifactWorker extends SwingWorker<Integer, Integer> {
List<TableReportModule> tableModules;
List<ARTIFACT_TYPE> artifactTypes;
// Create an ArtifactWorker with the enabled/disabled state of all Artifacts
ArtifactWorker(Map<ARTIFACT_TYPE, Boolean> artifactStates) {
tableModules = new ArrayList<TableReportModule>();
for (Entry<TableReportModule, ReportProgressPanel> entry : tableProgress.entrySet()) {
tableModules.add(entry.getKey());
}
artifactTypes = new ArrayList<ARTIFACT_TYPE>();
for (Entry<ARTIFACT_TYPE, Boolean> entry : artifactStates.entrySet()) {
if (entry.getValue()) {
artifactTypes.add(entry.getKey());
}
}
}
@Override
protected Integer doInBackground() throws Exception {
// Start the report
for (TableReportModule module : tableModules) {
ReportProgressPanel progress = tableProgress.get(module);
if (progress.getStatus() != ReportStatus.CANCELED) {
module.startReport(reportPath);
progress.start();
progress.setIndeterminate(false);
progress.setMaximumProgress(ARTIFACT_TYPE.values().length);
}
}
// For every enabled artifact type
for (ARTIFACT_TYPE type : artifactTypes) {
// Check to see if all the TableReportModules have been canceled
if (tableModules.isEmpty()) {
break;
}
Iterator<TableReportModule> iter = tableModules.iterator();
while (iter.hasNext()) {
TableReportModule module = iter.next();
if (tableProgress.get(module).getStatus() == ReportStatus.CANCELED) {
iter.remove();
}
}
// If the type is keyword hit or hashset hit, use the helper
if (type.equals(ARTIFACT_TYPE.TSK_KEYWORD_HIT)) {
writeKeywordHits(tableModules);
continue;
} else if (type.equals(ARTIFACT_TYPE.TSK_HASHSET_HIT)) {
writeHashsetHits(tableModules);
continue;
}
// Otherwise setup the unsorted list of artifacts, to later be sorted
List<String> titles = getArtifactRowTitles(type.getTypeID());
ArtifactComparator c = new ArtifactComparator();
List<Entry<BlackboardArtifact, List<BlackboardAttribute>>> unsortedArtifacts = new ArrayList<Entry<BlackboardArtifact, List<BlackboardAttribute>>>();
try {
// For every artifact of the current type, add it and it's attributes to a list
for (BlackboardArtifact artifact : skCase.getBlackboardArtifacts(type)) {
try {
unsortedArtifacts.add(new ArtifactEntry<BlackboardArtifact, List<BlackboardAttribute>>(artifact, skCase.getBlackboardAttributes(artifact)));
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to get Blackboard Attributes when generating report.", ex);
}
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Failed to get Blackboard Artifacts when generating report.", ex);
}
// The most efficient way to sort all the Artifacts is to add them to a List, and then
// sort that List based off a Comparator. Adding to a TreeMap/Set/List sorts the list
// each time an element is added, which adds unnecessary overhead if we only need it sorted once.
Collections.sort(unsortedArtifacts, c);
// For every module start a new data type based off this Artifact type
for (TableReportModule module : tableModules) {
tableProgress.get(module).updateStatusLabel("Now processing " + type.getDisplayName() + "...");
module.startDataType(type.getDisplayName());
module.startTable(titles);
}
// Add a row for every artifact
for (Entry<BlackboardArtifact, List<BlackboardAttribute>> artifactEntry : unsortedArtifacts) {
for (TableReportModule module : tableModules) {
try {
module.addRow(getArtifactRow(artifactEntry, module));
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Failed get Blackboard Artifact information to fill row.", ex);
}
}
}
// Finish up this data type
for (TableReportModule module : tableModules) {
tableProgress.get(module).increment();
module.endTable();
module.endDataType();
}
}
// End the report
for (TableReportModule module : tableModules) {
tableProgress.get(module).complete();
module.endReport();
}
return 0;
}
}
/**
* Write the keyword hits to the provided TableReportModules.
* @param tableModules modules to report on
*/
private void writeKeywordHits(List<TableReportModule> tableModules) {
ResultSet listsRs = null;
try {
// Query for keyword lists
listsRs = skCase.runQuery("SELECT att.value_text AS list " +
"FROM blackboard_attributes AS att, blackboard_artifacts AS art " +
"WHERE att.attribute_type_id = " + ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + " " +
"AND art.artifact_type_id = " + ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() + " " +
"AND att.artifact_id = art.artifact_id " +
"GROUP BY list");
List<String> lists = new ArrayList<String>();
while(listsRs.next()) {
String list = listsRs.getString("list");
if(list.isEmpty()) {
list = "User Searches";
}
lists.add(list);
}
// Make keyword data type and give them set index
for (TableReportModule module : tableModules) {
module.startDataType(ARTIFACT_TYPE.TSK_KEYWORD_HIT.getDisplayName());
module.addSetIndex(lists);
tableProgress.get(module).updateStatusLabel("Now processing "
+ ARTIFACT_TYPE.TSK_KEYWORD_HIT.getDisplayName() + "...");
}
}
catch (SQLException ex) {
logger.log(Level.SEVERE, "Failed to query keyword lists.", ex);
} finally {
if (listsRs != null) {
try {
skCase.closeRunQuery(listsRs);
} catch (SQLException ex) {
}
}
}
ResultSet rs = null;
try {
// Query for keywords
rs = skCase.runQuery("SELECT art.obj_id, att1.value_text AS keyword, att2.value_text AS preview, att3.value_text AS list, f.name AS name " +
"FROM blackboard_artifacts AS art, blackboard_attributes AS att1, blackboard_attributes AS att2, blackboard_attributes AS att3, tsk_files AS f " +
"WHERE (att1.artifact_id = art.artifact_id) " +
"AND (att2.artifact_id = art.artifact_id) " +
"AND (att3.artifact_id = art.artifact_id) " +
"AND (f.obj_id = art.obj_id) " +
"AND (att1.attribute_type_id = " + ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID() + ") " +
"AND (att2.attribute_type_id = " + ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW.getTypeID() + ") " +
"AND (att3.attribute_type_id = " + ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + ") " +
"AND (art.artifact_type_id = " + ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() + ") " +
"ORDER BY list, keyword, name");
String currentKeyword = "";
String currentList = "";
while (rs.next()) {
// Check to see if all the TableReportModules have been canceled
if (tableModules.isEmpty()) {
break;
}
Iterator<TableReportModule> iter = tableModules.iterator();
while (iter.hasNext()) {
TableReportModule module = iter.next();
if (tableProgress.get(module).getStatus() == ReportStatus.CANCELED) {
iter.remove();
}
}
Long objId = rs.getLong("obj_id");
String keyword = rs.getString("keyword");
String preview = rs.getString("preview");
String list = rs.getString("list");
String name = rs.getString("name");
String uniquePath = "";
try {
uniquePath = skCase.getAbstractFileById(objId).getUniquePath();
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Failed to get Abstract File by ID.", ex);
}
// If the lists aren't the same, we've started a new list
if((!list.equals(currentList) && !list.isEmpty()) || (list.isEmpty() && !currentList.equals("User Searches"))) {
if(!currentList.isEmpty()) {
for (TableReportModule module : tableModules) {
module.endTable();
module.endSet();
}
}
currentList = list.isEmpty() ? "User Searches" : list;
currentKeyword = ""; // reset the current keyword because it's a new list
for (TableReportModule module : tableModules) {
module.startSet(currentList);
tableProgress.get(module).updateStatusLabel("Now processing "
+ ARTIFACT_TYPE.TSK_KEYWORD_HIT.getDisplayName()
+ " (" + currentList + ")...");
}
}
if (!keyword.equals(currentKeyword)) {
if(!currentKeyword.equals("")) {
for (TableReportModule module : tableModules) {
module.endTable();
}
}
currentKeyword = keyword;
for (TableReportModule module : tableModules) {
module.addSetElement(currentKeyword);
module.startTable(getArtifactRowTitles(ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()));
}
}
String previewreplace = EscapeUtil.escapeHtml(preview);
for (TableReportModule module : tableModules) {
module.addRow(Arrays.asList(new String[] {name, previewreplace.replaceAll("<!", ""), uniquePath}));
}
}
// Finish the current data type
for (TableReportModule module : tableModules) {
tableProgress.get(module).increment();
module.endDataType();
}
} catch (SQLException ex) {
logger.log(Level.SEVERE, "Failed to query keywords.", ex);
} finally {
if (rs != null) {
try {
skCase.closeRunQuery(rs);
} catch (SQLException ex) {
}
}
}
}
/**
* Write the hashset hits to the provided TableReportModules.
* @param tableModules modules to report on
*/
private void writeHashsetHits(List<TableReportModule> tableModules) {
ResultSet listsRs = null;
try {
// Query for hashsets
listsRs = skCase.runQuery("SELECT att.value_text AS list " +
"FROM blackboard_attributes AS att, blackboard_artifacts AS art " +
"WHERE att.attribute_type_id = " + ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + " " +
"AND art.artifact_type_id = " + ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID() + " " +
"AND att.artifact_id = art.artifact_id " +
"GROUP BY list");
List<String> lists = new ArrayList<String>();
while(listsRs.next()) {
lists.add(listsRs.getString("list"));
}
// Make hashset data type and give them set index
for (TableReportModule module : tableModules) {
module.startDataType(ARTIFACT_TYPE.TSK_HASHSET_HIT.getDisplayName());
module.addSetIndex(lists);
tableProgress.get(module).updateStatusLabel("Now processing "
+ ARTIFACT_TYPE.TSK_HASHSET_HIT.getDisplayName() + "...");
}
} catch (SQLException ex) {
logger.log(Level.SEVERE, "Failed to query hashset lists.", ex);
} finally {
if (listsRs != null) {
try {
skCase.closeRunQuery(listsRs);
} catch (SQLException ex) {
}
}
}
ResultSet rs = null;
try {
// Query for hashset hits
rs = skCase.runQuery("SELECT art.obj_id, att.value_text AS setname, f.name AS name, f.size AS size " +
"FROM blackboard_artifacts AS art, blackboard_attributes AS att, tsk_files AS f " +
"WHERE (att.artifact_id = art.artifact_id) " +
"AND (f.obj_id = art.obj_id) " +
"AND (att.attribute_type_id = " + ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID() + ") " +
"AND (art.artifact_type_id = " + ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID() + ") " +
"ORDER BY setname, name, size");
String currentSet = "";
while (rs.next()) {
// Check to see if all the TableReportModules have been canceled
if (tableModules.isEmpty()) {
break;
}
Iterator<TableReportModule> iter = tableModules.iterator();
while (iter.hasNext()) {
TableReportModule module = iter.next();
if (tableProgress.get(module).getStatus() == ReportStatus.CANCELED) {
iter.remove();
}
}
Long objId = rs.getLong("obj_id");
String set = rs.getString("setname");
String name = rs.getString("name");
String size = rs.getString("size");
String uniquePath = "";
try {
uniquePath = skCase.getAbstractFileById(objId).getUniquePath();
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Failed to get Abstract File from ID.", ex);
}
// If the sets aren't the same, we've started a new set
if(!set.equals(currentSet)) {
if(!currentSet.isEmpty()) {
for (TableReportModule module : tableModules) {
module.endTable();
module.endSet();
}
}
currentSet = set;
for (TableReportModule module : tableModules) {
module.startSet(currentSet);
module.startTable(getArtifactRowTitles(ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()));
tableProgress.get(module).updateStatusLabel("Now processing "
+ ARTIFACT_TYPE.TSK_HASHSET_HIT.getDisplayName()
+ " (" + currentSet + ")...");
}
}
// Add a row for this hit to every module
for (TableReportModule module : tableModules) {
module.addRow(Arrays.asList(new String[] {name, size, uniquePath}));
}
}
// Finish the current data type
for (TableReportModule module : tableModules) {
tableProgress.get(module).increment();
module.endDataType();
}
} catch (SQLException ex) {
logger.log(Level.SEVERE, "Failed to query hashsets hits.", ex);
} finally {
if (rs != null) {
try {
skCase.closeRunQuery(rs);
} catch (SQLException ex) {
}
}
}
}
/**
* For a given artifact type ID, return the list of the row titles we're reporting on.
*
* @param artifactTypeId artifact type ID
* @return List<String> row titles
*/
private List<String> getArtifactRowTitles(int artifactTypeId) {
switch (artifactTypeId) {
case 2: // TSK_WEB_BOOKMARK
return new ArrayList<String>(Arrays.asList(new String[] {"URL", "Title", "Date Accessed", "Program", "Source File"}));
case 3: // TSK_WEB_COOKIE
return new ArrayList<String>(Arrays.asList(new String[] {"URL", "Date/Time", "Name", "Value", "Program", "Source File"}));
case 4: // TSK_WEB_HISTORY
return new ArrayList<String>(Arrays.asList(new String[] {"URL", "Date Accessed", "Referrer", "Name", "Program", "Source File"}));
case 5: // TSK_WEB_DOWNLOAD
return new ArrayList<String>(Arrays.asList(new String[] {"Destination", "Source URL", "Date Accessed", "Program", "Source File"}));
case 6: // TSK_RECENT_OBJECT
return new ArrayList<String>(Arrays.asList(new String[] {"Path", "Source File"}));
case 8: // TSK_INSTALLED_PROG
return new ArrayList<String>(Arrays.asList(new String[] {"Program Name", "Install Date/Time", "Source File"}));
case 9: // TSK_KEYWORD_HIT
return new ArrayList<String>(Arrays.asList(new String[] {"File Name", "Preview", "File Path"}));
case 10: // TSK_HASHSET_HIT
return new ArrayList<String>(Arrays.asList(new String[] {"File Name", "Size", "File Path"}));
case 11: // TSK_DEVICE_ATTACHED
return new ArrayList<String>(Arrays.asList(new String[] {"Name", "Device ID", "Date/Time", "Source File"}));
case 15: // TSK_WEB_SEARCH_QUERY
return new ArrayList<String>(Arrays.asList(new String[] {"Text", "Domain", "Date Accessed", "Program Name", "Source File"}));
case 16: // TSK_METADATA_EXIF
return new ArrayList<String>(Arrays.asList(new String[] {"File Name", "Date Taken", "Device Manufacturer", "Device Model", "Latitude", "Longitude", "Source File"}));
case 17: // TSK_TAG_FILE
return new ArrayList<String>(Arrays.asList(new String[] {"Comment", "File Name", "Source File"}));
case 18: // TSK_TAG_ARTIFACT
return new ArrayList<String>(Arrays.asList(new String[] {"Comment", "File Name", "Source File"}));
}
return null;
}
/**
* Map all BlackboardAttributes' values in a list of BlackboardAttributes to each attribute's attribute
* type ID, using module's dateToString method for date/time conversions if a module is supplied.
*
* @param attList list of BlackboardAttributes to be mapped
* @param module the TableReportModule the mapping is for
* @return Map<Integer, String> of the BlackboardAttributes mapped to their attribute type ID
*/
public Map<Integer, String> getMappedAttributes(List<BlackboardAttribute> attList, TableReportModule... module) {
Map<Integer, String> attributes = new HashMap<Integer, String>();
int size = ATTRIBUTE_TYPE.values().length;
for (int n = 0; n <= size; n++) {
attributes.put(n, "");
}
for (BlackboardAttribute tempatt : attList) {
String value = "";
Integer type = tempatt.getAttributeTypeID();
if (type.equals(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()) || type.equals(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID())) {
if (module.length > 0) {
value = module[0].dateToString(tempatt.getValueLong());
} else {
SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
value = sdf.format(new java.util.Date((tempatt.getValueLong() * 1000)));
}
} else if(type.equals(ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID()) ||
type.equals(ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE.getTypeID()) ||
type.equals(ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE.getTypeID())) {
value = Double.toString(tempatt.getValueDouble());
} else {
value = tempatt.getValueString();
}
if (value == null) {
value = "";
}
value = EscapeUtil.escapeHtml(value);
attributes.put(type, value);
}
return attributes;
}
/**
* Get a list of Strings with all the row values for a given BlackboardArtifact and
* list of BlackboardAttributes Entry, basing the date/time field on the given TableReportModule.
*
* @param entry BlackboardArtifact and list of BlackboardAttributes
* @param module TableReportModule for which the row is desired
* @return List<String> row values
* @throws TskCoreException
*/
private List<String> getArtifactRow(Entry<BlackboardArtifact, List<BlackboardAttribute>> entry, TableReportModule module) throws TskCoreException {
Map<Integer, String> attributes = getMappedAttributes(entry.getValue(), module);
switch (entry.getKey().getArtifactTypeID()) {
case 2: // TSK_WEB_BOOKMARK
List<String> bookmark = new ArrayList<String>();
bookmark.add(attributes.get(ATTRIBUTE_TYPE.TSK_URL.getTypeID()));
bookmark.add(attributes.get(ATTRIBUTE_TYPE.TSK_TITLE.getTypeID()));
bookmark.add(attributes.get(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()));
bookmark.add(attributes.get(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
bookmark.add(getFileUniquePath(entry.getKey().getObjectID()));
return bookmark;
case 3: // TSK_WEB_COOKIE
List<String> cookie = new ArrayList<String>();
cookie.add(attributes.get(ATTRIBUTE_TYPE.TSK_URL.getTypeID()));
cookie.add(attributes.get(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
cookie.add(attributes.get(ATTRIBUTE_TYPE.TSK_NAME.getTypeID()));
cookie.add(attributes.get(ATTRIBUTE_TYPE.TSK_VALUE.getTypeID()));
cookie.add(attributes.get(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
cookie.add(getFileUniquePath(entry.getKey().getObjectID()));
return cookie;
case 4: // TSK_WEB_HISTORY
List<String> history = new ArrayList<String>();
history.add(attributes.get(ATTRIBUTE_TYPE.TSK_URL.getTypeID()));
history.add(attributes.get(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()));
history.add(attributes.get(ATTRIBUTE_TYPE.TSK_REFERRER.getTypeID()));
history.add(attributes.get(ATTRIBUTE_TYPE.TSK_NAME.getTypeID()));
history.add(attributes.get(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
history.add(getFileUniquePath(entry.getKey().getObjectID()));
return history;
case 5: // TSK_WEB_DOWNLOAD
List<String> download = new ArrayList<String>();
download.add(attributes.get(ATTRIBUTE_TYPE.TSK_PATH.getTypeID()));
download.add(attributes.get(ATTRIBUTE_TYPE.TSK_URL.getTypeID()));
download.add(attributes.get(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()));
download.add(attributes.get(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
download.add(getFileUniquePath(entry.getKey().getObjectID()));
return download;
case 6: // TSK_RECENT_OBJECT
List<String> recent = new ArrayList<String>();
recent.add(attributes.get(ATTRIBUTE_TYPE.TSK_PATH.getTypeID()));
recent.add(getFileUniquePath(entry.getKey().getObjectID()));
return recent;
case 8: // TSK_INSTALLED_PROG
List<String> installed = new ArrayList<String>();
installed.add(attributes.get(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
installed.add(attributes.get(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
installed.add(getFileUniquePath(entry.getKey().getObjectID()));
return installed;
case 11: // TSK_DEVICE_ATTACHED
List<String> devices = new ArrayList<String>();
devices.add(attributes.get(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL.getTypeID()));
devices.add(attributes.get(ATTRIBUTE_TYPE.TSK_DEVICE_ID.getTypeID()));
devices.add(attributes.get(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
devices.add(getFileUniquePath(entry.getKey().getObjectID()));
return devices;
case 15: // TSK_WEB_SEARCH_QUERY
List<String> search = new ArrayList<String>();
search.add(attributes.get(ATTRIBUTE_TYPE.TSK_TEXT.getTypeID()));
search.add(attributes.get(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID()));
search.add(attributes.get(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()));
search.add(attributes.get(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
search.add(getFileUniquePath(entry.getKey().getObjectID()));
return search;
case 16: // TSK_METADATA_EXIF
List<String> exif = new ArrayList<String>();
exif.add(attributes.get(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
exif.add(attributes.get(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE.getTypeID()));
exif.add(attributes.get(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL.getTypeID()));
exif.add(attributes.get(ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID()));
exif.add(attributes.get(ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE.getTypeID()));
exif.add(getFileUniquePath(entry.getKey().getObjectID()));
return exif;
case 17: // TSK_TAG_FILE
List<String> tagFile = new ArrayList<String>();
tagFile.add(attributes.get(ATTRIBUTE_TYPE.TSK_COMMENT.getTypeID()));
AbstractFile tFile = getAbstractFile(entry.getKey().getObjectID());
if(tFile != null) {
tagFile.add(tFile.getName());
tagFile.add(tFile.getUniquePath());
} else {
tagFile.add("");
tagFile.add("");
}
return tagFile;
case 18: // TSK_TAG_ARTIFACT
List<String> tagArtifact = new ArrayList<String>();
tagArtifact.add(attributes.get(ATTRIBUTE_TYPE.TSK_COMMENT.getTypeID()));
AbstractFile aFile = getAbstractFile(entry.getKey().getObjectID());
if(aFile != null) {
tagArtifact.add(aFile.getName());
tagArtifact.add(aFile.getUniquePath());
} else {
tagArtifact.add("");
tagArtifact.add("");
}
return tagArtifact;
}
return null;
}
/**
* Given a tsk_file's obj_id, return the unique path of that file.
*
* @param objId tsk_file obj_id
* @return String unique path
*/
private String getFileUniquePath(long objId) {
try {
return skCase.getAbstractFileById(objId).getUniquePath();
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Failed to get Abstract File by ID.", ex);
}
return "";
}
/**
* Given a tsk_file's obj_id, return the name of that file.
*
* @param objId tsk_file obj_id
* @return String name
*/
private String getFileName(long objId) {
try {
return skCase.getAbstractFileById(objId).getName();
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Failed to get Abstract File by ID.", ex);
}
return "";
}
/**
* Return the file associated with a tsk_file obj_id.
*
* @param objId tsk_file obj_id
* @return AbstractFile associated with objId
*/
private AbstractFile getAbstractFile(long objId) {
try {
return skCase.getAbstractFileById(objId);
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Failed to get Abstract File by ID.", ex);
}
return null;
}
/**
* Map.Entry for BlackboardArtifacts and lists of BlackboardAttributes.
*
* @param <K> BlackboardArtifact
* @param <V> List<BlackboardAttribute>
*/
private class ArtifactEntry<K, V> implements Map.Entry<BlackboardArtifact, List<BlackboardAttribute>> {
BlackboardArtifact artifact;
List<BlackboardAttribute> attributes;
private ArtifactEntry(BlackboardArtifact artifact, List<BlackboardAttribute> attributes) {
this.artifact = artifact;
this.attributes = attributes;
}
@Override
public BlackboardArtifact getKey() {
return artifact;
}
@Override
public List<BlackboardAttribute> getValue() {
return attributes;
}
@Override
public List<BlackboardAttribute> setValue(List<BlackboardAttribute> value) {
List<BlackboardAttribute> old = attributes;
attributes = value;
return old;
}
}
/**
* Compares entries of BlackboardArtifacts and lists of BlackboardAttributes, sorting by
* the first attribute both artifacts have in common. If all attributes are the same, they are
* assumed duplicates, and they are sorted on artifact ID. Should only be used on artifacts
* of similar types.
*/
private class ArtifactComparator implements Comparator<Entry<BlackboardArtifact, List<BlackboardAttribute>>> {
@Override
public int compare(Entry<BlackboardArtifact, List<BlackboardAttribute>> art1, Entry<BlackboardArtifact, List<BlackboardAttribute>> art2) {
// Get all the attributes for each artifact
int size = ATTRIBUTE_TYPE.values().length;
Map<Integer, String> att1 = getMappedAttributes(art1.getValue());
Map<Integer, String> att2 = getMappedAttributes(art2.getValue());
// Compare the attributes one-by-one looking for differences
for(int i=0; i < size; i++) {
String a1 = att1.get(i);
String a2 = att2.get(i);
if((!a1.equals("") && !a2.equals("")) && a1.compareTo(a2) != 0) {
return a1.compareTo(a2);
}
}
// If all attributes are the same, they're most likely duplicates so sort by artifact ID
return ((Long)art1.getKey().getArtifactID()).compareTo((Long)art2.getKey().getArtifactID());
}
}
}
File diff suppressed because it is too large Load Diff
@@ -23,39 +23,11 @@
package org.sleuthkit.autopsy.report;
/**
* interface every reporting module should implement
* Interface extended by TableReportModule and GeneralReportModule.
* Contains vital report information to be used by every report.
*/
public interface ReportModule {
/**
* Generates a report on the current case Reporting module should traverse
* the blackboard, extract needed information as specified in the config and
* generate a report file
*
* @param config specifying parts that should be generated
* @return absolute file path to the report generated
* @throws ReportModuleException thrown when report generation failed
*/
public String generateReport(ReportConfiguration config) throws ReportModuleException;
/**
* This saves a copy of the report (current one) to another place specified
* by the user. Takes the input of where the path needs to be saved, include
* filename and extention.
*
* @param path file path where to save a copy of the report
* @throws ReportModuleException thrown if report saving failed
*/
public void save(String path) throws ReportModuleException;
/**
* Returns a short description of report type/file format this module
* generates for instance, "XML", "Excel"
*
* @return the report type short description
*/
public String getReportType();
/**
* Returns a basic string name for the report. What is 'officially' titled.
*
@@ -63,28 +35,12 @@ public interface ReportModule {
*/
public String getName();
/**
* Returns the report configuration object that was created
*
* @return the report configuration for this report
*/
public ReportConfiguration GetReportConfiguration();
/**
* Returns a one line user friendly description of the type of report this
* module generates
* @return user-friendly report description
*/
public String getReportTypeDescription();
/**
* Calls to the report module to execute a method to display the report that
* was generated.
*
* @param path the path to the file
*
*/
public void getPreview(String path);
public String getDescription();
/**
* Calls to the report module to execute a method to get the extension that
@@ -94,4 +50,11 @@ public interface ReportModule {
*
*/
public String getExtension();
/**
* Returns the path to the main (or only) file for the report.
*
* @return String path to the report file
*/
public String getFilePath();
}
@@ -1,35 +0,0 @@
/*
*
* Autopsy Forensic Browser
*
* Copyright 2012 Basis Technology Corp.
*
* Copyright 2012 42six Solutions.
* Contact: aebadirad <at> 42six <dot> com
* Project Contact/Architect: 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.report;
//exception thrown by a reporting module when report generation failed
class ReportModuleException extends Exception {
public ReportModuleException(String msg) {
super(msg);
}
public ReportModuleException(String msg, Exception ex) {
super(msg, ex);
}
}
@@ -1,282 +0,0 @@
/*
*
* Autopsy Forensic Browser
*
* Copyright 2012 Basis Technology Corp.
*
* Copyright 2012 42six Solutions.
* Contact: aebadirad <at> 42six <dot> com
* Project Contact/Architect: 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.report;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.FileUtil;
import org.sleuthkit.autopsy.coreutils.Logger;
public class ReportPanel extends javax.swing.JPanel {
private ReportPanelAction rpa;
private static final Logger logger = Logger.getLogger(ReportPanel.class.getName());
/**
* Creates new form ReportPanel
*/
public ReportPanel(ReportPanelAction reportPanelAction) {
initComponents();
rpa = reportPanelAction;
}
/**
* 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() {
reportScrollPane = new javax.swing.JScrollPane();
reportSummaryPanel = new javax.swing.JPanel();
closeButton = new javax.swing.JButton();
exportButton = new javax.swing.JButton();
statusLabel = new javax.swing.JLabel();
LABEL_LOC = new javax.swing.JLabel();
ButtonOpenFolder = new javax.swing.JButton();
reportScrollPane.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(ReportPanel.class, "ReportPanel.reportScrollPane.border.title"))); // NOI18N
javax.swing.GroupLayout reportSummaryPanelLayout = new javax.swing.GroupLayout(reportSummaryPanel);
reportSummaryPanel.setLayout(reportSummaryPanelLayout);
reportSummaryPanelLayout.setHorizontalGroup(
reportSummaryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 675, Short.MAX_VALUE)
);
reportSummaryPanelLayout.setVerticalGroup(
reportSummaryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 214, Short.MAX_VALUE)
);
reportScrollPane.setViewportView(reportSummaryPanel);
org.openide.awt.Mnemonics.setLocalizedText(closeButton, org.openide.util.NbBundle.getMessage(ReportPanel.class, "ReportPanel.closeButton.text_1")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(exportButton, org.openide.util.NbBundle.getMessage(ReportPanel.class, "ReportPanel.exportButton.text")); // NOI18N
exportButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
exportButtonActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(statusLabel, org.openide.util.NbBundle.getMessage(ReportPanel.class, "ReportPanel.statusLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(LABEL_LOC, org.openide.util.NbBundle.getMessage(ReportPanel.class, "ReportPanel.LABEL_LOC.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(ButtonOpenFolder, org.openide.util.NbBundle.getMessage(ReportPanel.class, "ReportPanel.ButtonOpenFolder.text_1")); // NOI18N
ButtonOpenFolder.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
ButtonOpenFolderActionPerformed(evt);
}
});
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()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(reportScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 404, Short.MAX_VALUE)
.addComponent(statusLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addComponent(LABEL_LOC)
.addGap(0, 0, Short.MAX_VALUE))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(0, 0, Short.MAX_VALUE)
.addComponent(exportButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(ButtonOpenFolder)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(closeButton)))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(reportScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 125, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(statusLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(LABEL_LOC)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(closeButton)
.addComponent(exportButton)
.addComponent(ButtonOpenFolder))
.addGap(8, 8, 8))
);
}// </editor-fold>//GEN-END:initComponents
private void exportButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportButtonActionPerformed
HashMap<ReportModule, String> reports = rpa.getReports();
exportReportAction(reports);
}//GEN-LAST:event_exportButtonActionPerformed
private void ButtonOpenFolderActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ButtonOpenFolderActionPerformed
String path = Case.getCurrentCase().getCaseDirectory() + File.separator + "Reports";
File dir = new File(path);
if (Desktop.isDesktopSupported()) {
try {
Desktop.getDesktop().open(dir);
} catch (IOException ioe) {
logger.log(Level.WARNING, "Could not open folder [" + path + "]", ioe);
}
}
}//GEN-LAST:event_ButtonOpenFolderActionPerformed
public void setCloseButtonActionListener(ActionListener e) {
closeButton.addActionListener(e);
}
public void setFinishedReportText() {
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
String reportText = "These reports were generated on " + dateFormat.format(new Date()) + ".";
String loc = "Reports extracted to: " + Case.getCurrentCase().getCaseDirectory() + File.separator + "Reports";
statusLabel.setText(reportText);
LABEL_LOC.setText(loc);
final JPanel tempPanel = new JPanel(new GridBagLayout());
//tempPanel.setMinimumSize(new Dimension(540,240));
SwingUtilities.invokeLater(new Runnable() {
GridBagConstraints c = new GridBagConstraints();
@Override
public void run() {
HashMap<ReportModule, String> reports = rpa.getReports();
int cc = 0;
for (Map.Entry<ReportModule, String> entry : reports.entrySet()) {
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
c.gridwidth = 1;
c.gridx = 0;
c.gridy = cc;
c.insets = new Insets(0, 0, 0, 0); // remove padding
String info = entry.getKey().getName() + " report";
JLabel infoLabel = new JLabel(info);
tempPanel.add(infoLabel, c);
c.fill = GridBagConstraints.BASELINE_TRAILING;
c.weightx = 0.0;
c.gridwidth = 1;
c.gridheight = 1;
c.gridx = 1;
c.gridy = cc;
JButton viewButton = new JButton("View Report");
final ReportModule rep = entry.getKey();
final String path = entry.getValue();
viewButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
rep.getPreview(path);
}
});
tempPanel.add(viewButton, c);
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1;
c.gridwidth = 3;
c.gridheight = 1;
c.gridx = 0;
c.gridy = ++cc;
c.insets = new Insets(0, 0, 15, 0); // row padding
tempPanel.revalidate();
tempPanel.repaint();
cc++;
}
}
});
reportSummaryPanel.setLayout(new GridLayout(0, 1));
reportSummaryPanel.add(tempPanel, 0);
//reportScrollPane.revalidate();
//reportScrollPane.repaint();
}
private void exportReportAction(HashMap<ReportModule, String> reports) {
JFileChooser exportChooser = new JFileChooser();
int option = exportChooser.showSaveDialog(this);
if (option == JFileChooser.APPROVE_OPTION) {
if (exportChooser.getSelectedFile() != null) {
File file = exportChooser.getSelectedFile();
String path = file.getParent();
String name = file.getName();
for (Map.Entry<ReportModule, String> entry : reports.entrySet()) {
exportReport(path, name, entry);
}
}
}
}
private void exportReport(String path, String name, Map.Entry<ReportModule, String> entry) {
ReportModule report = entry.getKey();
String ext = report.getExtension();
String original = entry.getValue();
try {
if(report.getName().equals("HTML")) {
String newpath = FileUtil.copyFolder(original.substring(0, original.lastIndexOf("\\")), path, name);
JOptionPane.showMessageDialog(this, "\n" + report.getName() + " report has been successfully saved to: \n" + newpath);
} else {
String newpath = FileUtil.copyFile(original, path, name + "-" + report.getName(), ext, true);
JOptionPane.showMessageDialog(this, "\n" + report.getName() + " report has been successfully saved to: \n" + newpath);
}
} catch (IOException ex) {
JOptionPane.showMessageDialog(this, "\n" + report.getName() + " report has failed to save! \n Reason: " + ex);
}
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton ButtonOpenFolder;
private javax.swing.JLabel LABEL_LOC;
private javax.swing.JButton closeButton;
private javax.swing.JButton exportButton;
private javax.swing.JScrollPane reportScrollPane;
private javax.swing.JPanel reportSummaryPanel;
private javax.swing.JLabel statusLabel;
// End of variables declaration//GEN-END:variables
}
@@ -1,163 +0,0 @@
/*
*
* Autopsy Forensic Browser
*
* Copyright 2012 Basis Technology Corp.
*
* Copyright 2012 42six Solutions.
* Contact: aebadirad <at> 42six <dot> com
* Project Contact/Architect: 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.report;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.logging.Level;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import org.sleuthkit.autopsy.coreutils.Logger;
public class ReportPanelAction {
private static final String ACTION_NAME = "Report Preview";
private StringBuilder viewReport = new StringBuilder();
private int cc = 1;
private HashMap<ReportModule,String> reports = new HashMap<ReportModule,String>();
public ReportPanelAction() {
}
public void reportGenerate(final ReportConfiguration reportconfig, final ArrayList<String> classList, final ArrayList<String> preview, final ReportFilter rr) {
try {
//Clear any old reports in the string
viewReport.setLength(0);
// Generate the reports and create the hashmap
final ReportGen report = new ReportGen();
//see what reports we need to run and run them
//Set progress bar to move while doing this
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
rr.progBarStartText();
}
});
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
rr.progBarCount(((classList.size())*2)+1);
}
});
// Advance the bar a bit so the user knows something is happening
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
rr.progBarSet(1);
}
});
//Turn our results into the appropriate xml/html reports
//TODO: add a way for users to select what they will run when
Thread reportThread = new Thread(new Runnable() {
@Override
public void run() {
reports.clear();
for (String s : classList) {
try {
rr.progBarSet(cc);
final Class reportclass = Class.forName(s);
rr.setUpdateLabel("Running " + reportclass.getSimpleName() + " report...");
Object reportObject = reportclass.newInstance();
Class[] argTypes = new Class[]{ReportConfiguration.class};
Method generatereport = reportclass.getDeclaredMethod("generateReport", argTypes);
Object invoke = generatereport.invoke(reportObject, reportconfig);
rr.progBarSet(cc);
String path = invoke.toString();
reports.put((ReportModule) reportObject, path);
} catch (Exception e) {
Logger.getLogger(ReportFilterAction.class.getName()).log(Level.WARNING, "Error generating " + s + "! Reason: ", e);
}
}
}
});
// start our threads
reportThread.start();
// display the window
// create the popUp window for it
if (ReportFilter.cancel == false) {
final JFrame frame = new JFrame(ACTION_NAME);
final JDialog popUpWindow = new JDialog(frame, ACTION_NAME, true); // to make the popUp Window to be modal
// initialize panel with loaded settings
//Set the temporary label to let the user know its done and is waiting on the report
final ReportPanel panel = new ReportPanel(this);
panel.setCloseButtonActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
popUpWindow.dispose();
}
});
// add the panel to the popup window
popUpWindow.add(panel);
popUpWindow.setResizable(true);
popUpWindow.pack();
// set the location of the popUp Window on the center of the screen
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
double w = popUpWindow.getSize().getWidth();
double h = popUpWindow.getSize().getHeight();
popUpWindow.setLocation((int) ((screenDimension.getWidth() - w) / 2), (int) ((screenDimension.getHeight() - h) / 2));
reportThread.join();
rr.progBarText();
rr.progBarDone();
panel.setFinishedReportText();
popUpWindow.setVisible(true);
}
} catch (Exception ex) {
Logger.getLogger(ReportFilterAction.class.getName()).log(Level.WARNING, "Error displaying " + ACTION_NAME + " window.", ex);
}
}
public HashMap<ReportModule,String> getReports(){
return reports;
}
}
@@ -0,0 +1,128 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[486, 68]"/>
</Property>
</Properties>
<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 max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="processingLabel" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="reportProgressBar" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="cancelButton" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="reportLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="separationLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="pathLabel" pref="548" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace 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 max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="cancelButton" max="32767" attributes="0"/>
<Component id="reportProgressBar" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="reportLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="pathLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="separationLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Component id="processingLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="20" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JProgressBar" name="reportProgressBar">
</Component>
<Component class="javax.swing.JButton" name="cancelButton">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/report/images/report_loading.png"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportProgressPanel.cancelButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportProgressPanel.cancelButton.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
<Property name="borderPainted" type="boolean" value="false"/>
<Property name="contentAreaFilled" type="boolean" value="false"/>
<Property name="focusPainted" type="boolean" value="false"/>
</Properties>
<Events>
<EventHandler event="mouseEntered" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="cancelButtonMouseEntered"/>
<EventHandler event="mouseExited" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="cancelButtonMouseExited"/>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="reportLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="11" style="1"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportProgressPanel.reportLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="pathLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportProgressPanel.pathLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="processingLabel">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="10" style="2"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportProgressPanel.processingLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="separationLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportProgressPanel.separationLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>
@@ -0,0 +1,396 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2012 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.report;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Desktop;
import java.awt.EventQueue;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.IOException;
public class ReportProgressPanel extends javax.swing.JPanel {
private ReportStatus STATUS;
// Enum to represent if a report is waiting,
// running, done, or has been canceled
public enum ReportStatus {
QUEUING,
RUNNING,
COMPLETE,
CANCELED
}
/**
* Creates new form ReportProgressPanel
*/
public ReportProgressPanel(String reportName, String reportPath) {
initComponents();
customInit(reportName, reportPath);
}
private void customInit(String reportName, String reportPath) {
reportLabel.setText(reportName);
pathLabel.setText("<html><u>" + shortenPath(reportPath) + "</u></html>");
pathLabel.setToolTipText(reportPath);
reportProgressBar.setIndeterminate(true);
reportProgressBar.setMaximum(100);
processingLabel.setText("Queuing...");
STATUS = ReportStatus.QUEUING;
// Add the "link" effect to the pathLabel
final String linkPath = reportPath;
pathLabel.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
File file = new File(linkPath);
try {
Desktop.getDesktop().open(file);
} catch (IOException ex) {
} catch (IllegalArgumentException ex) {
try {
// try to open the parent path if the file doens't exist
Desktop.getDesktop().open(file.getParentFile());
} catch (IOException ex1) {
}
}
}
@Override
public void mouseEntered(MouseEvent e) {
pathLabel.setForeground(Color.DARK_GRAY);
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
@Override
public void mouseExited(MouseEvent e) {
pathLabel.setForeground(Color.BLACK);
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
});
}
/**
* Return a shortened version of the given path.
*/
private String shortenPath(String path) {
if (path.length() > 100) {
path = path.substring(0, 10 + path.substring(10).indexOf(File.separator) + 1) + "..."
+ path.substring((path.length() - 70) + path.substring(path.length() - 70).indexOf(File.separator));
}
return path;
}
/**
* Return the current ReportStatus of this report.
*
* @return ReportStatus status of this report
*/
public ReportStatus getStatus() {
return STATUS;
}
/**
* Start the JProgressBar for this report.
*
* Enables the cancelButton, updates the processingLabel, and changes this
* report's ReportStatus.
*/
public void start() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
cancelButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/report/images/report_cancel.png")));
cancelButton.setToolTipText("Cancel");
processingLabel.setText("Starting report...");
STATUS = ReportStatus.RUNNING;
}
});
}
/**
* Set the maximum progress for this report's JProgressBar.
*
* @param max maximum progress for JProgressBar
*/
public void setMaximumProgress(final int max) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
if (STATUS != ReportStatus.CANCELED) {
reportProgressBar.setMaximum(max);
}
}
});
}
/**
* Increment the JProgressBar for this report by one unit.
*/
public void increment() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
if (STATUS != ReportStatus.CANCELED) {
reportProgressBar.setValue(reportProgressBar.getValue() + 1);
}
}
});
}
/**
* Set the value of the JProgressBar for this report.
*
* @param value value to be set at
*/
public void setProgress(final int value) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
if (STATUS != ReportStatus.CANCELED) {
reportProgressBar.setValue(value);
}
}
});
}
/**
* Changes the status of the JProgressBar to be determinate or indeterminate.
*
* @param indeterminate sets the JProgressBar to be indeterminate if true, determinate otherwise
*/
public void setIndeterminate(final boolean indeterminate) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
if (STATUS != ReportStatus.CANCELED) {
reportProgressBar.setIndeterminate(indeterminate);
}
}
});
}
/**
* Change the text of this report's status label. The text given will
* be the full text used.
* e.g. updateStatusLabel("Now processing files...")
* sets the label to "Now processing files..."
*
* @param status String to use as status
*/
public void updateStatusLabel(final String status) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
if (STATUS != ReportStatus.CANCELED) {
processingLabel.setText(status);
}
}
});
}
/**
* Declare the report completed.
* This will fill the JProgressBar, update the cancelButton to completed,
* and disallow any cancellation of this report.
*/
public void complete() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
if (STATUS != ReportStatus.CANCELED) {
STATUS = ReportStatus.COMPLETE;
processingLabel.setText("Complete");
reportProgressBar.setValue(reportProgressBar.getMaximum());
cancelButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/report/images/report_complete.png")));
cancelButton.setToolTipText("Complete");
}
}
});
// Do something with the button to change the icon and make not clickable
}
/**
* 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() {
reportProgressBar = new javax.swing.JProgressBar();
cancelButton = new javax.swing.JButton();
reportLabel = new javax.swing.JLabel();
pathLabel = new javax.swing.JLabel();
processingLabel = new javax.swing.JLabel();
separationLabel = new javax.swing.JLabel();
setMinimumSize(new java.awt.Dimension(486, 68));
cancelButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/report/images/report_loading.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(ReportProgressPanel.class, "ReportProgressPanel.cancelButton.text")); // NOI18N
cancelButton.setToolTipText(org.openide.util.NbBundle.getMessage(ReportProgressPanel.class, "ReportProgressPanel.cancelButton.toolTipText")); // NOI18N
cancelButton.setBorder(null);
cancelButton.setBorderPainted(false);
cancelButton.setContentAreaFilled(false);
cancelButton.setFocusPainted(false);
cancelButton.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseEntered(java.awt.event.MouseEvent evt) {
cancelButtonMouseEntered(evt);
}
public void mouseExited(java.awt.event.MouseEvent evt) {
cancelButtonMouseExited(evt);
}
});
cancelButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cancelButtonActionPerformed(evt);
}
});
reportLabel.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(reportLabel, org.openide.util.NbBundle.getMessage(ReportProgressPanel.class, "ReportProgressPanel.reportLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(pathLabel, org.openide.util.NbBundle.getMessage(ReportProgressPanel.class, "ReportProgressPanel.pathLabel.text")); // NOI18N
processingLabel.setFont(new java.awt.Font("Tahoma", 2, 10)); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(processingLabel, org.openide.util.NbBundle.getMessage(ReportProgressPanel.class, "ReportProgressPanel.processingLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(separationLabel, org.openide.util.NbBundle.getMessage(ReportProgressPanel.class, "ReportProgressPanel.separationLabel.text")); // NOI18N
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()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(processingLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addComponent(reportProgressBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cancelButton))
.addGroup(layout.createSequentialGroup()
.addComponent(reportLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(separationLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(pathLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 548, Short.MAX_VALUE)))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(cancelButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(reportProgressBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(reportLabel)
.addComponent(pathLabel)
.addComponent(separationLabel))
.addGap(0, 0, 0)
.addComponent(processingLabel)
.addContainerGap(20, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
cancel();
}//GEN-LAST:event_cancelButtonActionPerformed
/**
* Cancels the current report, based on it's status. If the report is
* complete or has already been completed, nothing happens.
*/
void cancel() {
switch(STATUS) {
case COMPLETE:
break;
case CANCELED:
break;
default:
STATUS = ReportStatus.CANCELED;
cancelButton.setEnabled(false);
cancelButton.setToolTipText("Canceled");
reportProgressBar.setIndeterminate(false);
reportProgressBar.setValue(0);
reportProgressBar.setForeground(Color.RED);
reportProgressBar.setBackground(Color.RED);
processingLabel.setForeground(Color.RED);
processingLabel.setText("Canceled");
break;
}
}
private void cancelButtonMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_cancelButtonMouseEntered
switch(STATUS) {
case COMPLETE:
break;
case CANCELED:
break;
default:
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
cancelButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/report/images/report_cancel_hover.png")));
break;
}
}//GEN-LAST:event_cancelButtonMouseEntered
private void cancelButtonMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_cancelButtonMouseExited
switch(STATUS) {
case COMPLETE:
break;
case CANCELED:
break;
case QUEUING:
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
cancelButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/report/images/report_loading.png")));
break;
case RUNNING:
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
cancelButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/report/images/report_cancel.png")));
break;
}
}//GEN-LAST:event_cancelButtonMouseExited
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton cancelButton;
private javax.swing.JLabel pathLabel;
private javax.swing.JLabel processingLabel;
private javax.swing.JLabel reportLabel;
private javax.swing.JProgressBar reportProgressBar;
private javax.swing.JLabel separationLabel;
// End of variables declaration//GEN-END:variables
}
@@ -1,61 +0,0 @@
/*
*
* Autopsy Forensic Browser
*
* Copyright 2012 Basis Technology Corp.
*
* Copyright 2012 42six Solutions.
* Contact: aebadirad <at> 42six <dot> com
* Project Contact/Architect: 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.report;
public class ReportUtils {
static String changeExtension(String originalName, String newExtension) {
int lastDot = originalName.lastIndexOf(".");
if (lastDot != -1) {
return originalName.substring(0, lastDot) + newExtension;
} else {
return originalName + newExtension;
}
}
/**
* Inserts a string into a string every n number of characters
*
* @param text the base string/text that you want to have manipulated
* @param insert the string you want to insert
* @param period how many characters it should input insert at
* @return string with the string inserts inserted
*/
public static String insertPeriodically(String text, String insert, int period) {
StringBuilder builder = new StringBuilder(
text.length() + insert.length() * (text.length() / period) + 1);
int index = 0;
String prefix = "";
while (index < text.length()) {
// Don't put the insert in the very first iteration.
// This is easier than appending it *after* each substring
builder.append(prefix);
prefix = insert;
builder.append(text.substring(index,
Math.min(index + period, text.length())));
index += period;
}
return builder.toString();
}
}
@@ -0,0 +1,139 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[650, 250]"/>
</Property>
</Properties>
<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" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="reportModulesLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="modulesScrollPane" alignment="0" min="-2" pref="186" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="configurationPanel" max="32767" attributes="0"/>
<Component id="descriptionScrollPane" max="32767" attributes="0"/>
</Group>
<EmptySpace 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 max="-2" attributes="0"/>
<Component id="reportModulesLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="modulesScrollPane" pref="208" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Component id="configurationPanel" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="descriptionScrollPane" min="-2" pref="32" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="modulesScrollPane">
<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.JTable" name="modulesTable">
<Properties>
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="f0" green="f0" red="f0" type="rgb"/>
</Property>
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
<Table columnCount="0" rowCount="0"/>
</Property>
<Property name="showHorizontalLines" type="boolean" value="false"/>
<Property name="showVerticalLines" type="boolean" value="false"/>
<Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor">
<TableHeader reorderingAllowed="true" resizingAllowed="true"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JLabel" name="reportModulesLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportVisualPanel1.reportModulesLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Container class="javax.swing.JPanel" name="configurationPanel">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo">
<LineBorder>
<Color PropertyName="color" blue="7d" green="7d" red="7d" type="rgb"/>
</LineBorder>
</Border>
</Property>
</Properties>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="432" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
</Container>
<Container class="javax.swing.JScrollPane" name="descriptionScrollPane">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
</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="descriptionTextPane">
<Properties>
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="f0" green="f0" red="f0" type="rgb"/>
</Property>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Form>
@@ -0,0 +1,298 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2012 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.report;
import java.awt.BorderLayout;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.swing.JPanel;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumn;
import org.openide.util.Lookup;
import org.sleuthkit.autopsy.coreutils.Logger;
public final class ReportVisualPanel1 extends JPanel {
private static final Logger logger = Logger.getLogger(ReportVisualPanel1.class.getName());
private ReportWizardPanel1 wizPanel;
private Map<TableReportModule, Boolean> tableModuleStates = new LinkedHashMap<TableReportModule, Boolean>();
private Map<GeneralReportModule, Boolean> generalModuleStates = new LinkedHashMap<GeneralReportModule, Boolean>();
private List<TableReportModule> tableModules = new ArrayList<TableReportModule>();
private List<GeneralReportModule> generalModules = new ArrayList<GeneralReportModule>();
private ModulesTableModel modulesModel;
private ModuleSelectionListener modulesListener;
/**
* Creates new form ReportVisualPanel1
*/
public ReportVisualPanel1(ReportWizardPanel1 wizPanel) {
initComponents();
initModules();
this.wizPanel = wizPanel;
configurationPanel.setLayout(new BorderLayout());
descriptionTextPane.setEditable(false);
modulesTable.setRowSelectionInterval(0, 0);
}
// Initialize the list of ReportModules
private void initModules() {
for(TableReportModule module : Lookup.getDefault().lookupAll(TableReportModule.class)) {
if(module.getName().equals("HTML")) {
tableModuleStates.put(module, Boolean.TRUE);
} else {
tableModuleStates.put(module, Boolean.FALSE);
}
tableModules.add(module);
}
for(GeneralReportModule module : Lookup.getDefault().lookupAll(GeneralReportModule.class)) {
generalModuleStates.put(module, Boolean.FALSE);
generalModules.add(module);
}
modulesModel = new ModulesTableModel();
modulesListener = new ModuleSelectionListener();
modulesTable.setModel(modulesModel);
modulesTable.getSelectionModel().addListSelectionListener(modulesListener);
modulesTable.setTableHeader(null);
modulesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
modulesTable.setRowHeight(modulesTable.getRowHeight() + 5);
int width = modulesScrollPane.getPreferredSize().width;
for (int i = 0; i < modulesTable.getColumnCount(); i++) {
TableColumn column = modulesTable.getColumnModel().getColumn(i);
if (i == 0) {
column.setPreferredWidth(((int) (width * 0.15)));
} else {
column.setPreferredWidth(((int) (width * 0.84)));
}
}
}
@Override
public String getName() {
return "Select and Configure Report Modules";
}
/**
* @return the enabled/disabled states of all TableReportModules
*/
Map<TableReportModule, Boolean> getTableModuleStates() {
return tableModuleStates;
}
/**
* @return the enabled/disabled states of all GeneralReportModules
*/
Map<GeneralReportModule, Boolean> getGeneralModuleStates() {
return generalModuleStates;
}
/**
* 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.
*/
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
modulesScrollPane = new javax.swing.JScrollPane();
modulesTable = new javax.swing.JTable();
reportModulesLabel = new javax.swing.JLabel();
configurationPanel = new javax.swing.JPanel();
descriptionScrollPane = new javax.swing.JScrollPane();
descriptionTextPane = new javax.swing.JTextPane();
setPreferredSize(new java.awt.Dimension(650, 250));
modulesTable.setBackground(new java.awt.Color(240, 240, 240));
modulesTable.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
},
new String [] {
}
));
modulesTable.setShowHorizontalLines(false);
modulesTable.setShowVerticalLines(false);
modulesScrollPane.setViewportView(modulesTable);
org.openide.awt.Mnemonics.setLocalizedText(reportModulesLabel, org.openide.util.NbBundle.getMessage(ReportVisualPanel1.class, "ReportVisualPanel1.reportModulesLabel.text")); // NOI18N
configurationPanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(125, 125, 125)));
javax.swing.GroupLayout configurationPanelLayout = new javax.swing.GroupLayout(configurationPanel);
configurationPanel.setLayout(configurationPanelLayout);
configurationPanelLayout.setHorizontalGroup(
configurationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 432, Short.MAX_VALUE)
);
configurationPanelLayout.setVerticalGroup(
configurationPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 0, Short.MAX_VALUE)
);
descriptionScrollPane.setBorder(null);
descriptionTextPane.setBackground(new java.awt.Color(240, 240, 240));
descriptionTextPane.setBorder(null);
descriptionScrollPane.setViewportView(descriptionTextPane);
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()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(reportModulesLabel)
.addComponent(modulesScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 186, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(10, 10, 10)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(configurationPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(descriptionScrollPane))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(reportModulesLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(modulesScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 208, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addComponent(configurationPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(descriptionScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap())
);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JPanel configurationPanel;
private javax.swing.JScrollPane descriptionScrollPane;
private javax.swing.JTextPane descriptionTextPane;
private javax.swing.JScrollPane modulesScrollPane;
private javax.swing.JTable modulesTable;
private javax.swing.JLabel reportModulesLabel;
// End of variables declaration//GEN-END:variables
private class ModulesTableModel extends AbstractTableModel {
@Override
public int getRowCount() {
return tableModules.size() + generalModules.size();
}
@Override
public int getColumnCount() {
return 2;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
ReportModule module;
if (rowIndex < tableModules.size()) {
module = tableModules.get(rowIndex);
} else {
module = generalModules.get(rowIndex - tableModules.size());
}
if (columnIndex == 0 && rowIndex < tableModules.size()) {
return tableModuleStates.get(tableModules.get(rowIndex));
} else if (columnIndex == 0 && rowIndex >= tableModules.size()) {
return generalModuleStates.get(generalModules.get(rowIndex - tableModules.size()));
} else {
return module.getName();
}
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return columnIndex == 0;
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
if (columnIndex == 0 && rowIndex < tableModules.size()) {
tableModuleStates.put(tableModules.get(rowIndex), (Boolean) aValue);
} else if (columnIndex == 0 && rowIndex >= tableModules.size()) {
generalModuleStates.put(generalModules.get(rowIndex - tableModules.size()), (Boolean) aValue);
}
// Check if there are any TableReportModules enabled
boolean tableModuleEnabled = false;
for (Entry<TableReportModule, Boolean> module : tableModuleStates.entrySet()) {
if (module.getValue()) {
tableModuleEnabled = true;
}
}
boolean generalModuleEnabled = false;
for (Entry<GeneralReportModule, Boolean> module : generalModuleStates.entrySet()) {
if (module.getValue()) {
generalModuleEnabled = true;
}
}
if(tableModuleEnabled) {
wizPanel.setNext(true);
wizPanel.setFinish(false);
} else if(generalModuleEnabled) {
wizPanel.setFinish(true);
wizPanel.setNext(false);
} else {
wizPanel.setFinish(false);
wizPanel.setNext(false);
}
}
@Override
public Class<?> getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
}
private class ModuleSelectionListener implements ListSelectionListener {
@Override
public void valueChanged(ListSelectionEvent e) {
configurationPanel.removeAll();
int rowIndex = modulesTable.getSelectedRow();
if (rowIndex < tableModules.size()) {
configurationPanel.add(new DefaultReportConfigurationPanel(), BorderLayout.CENTER);
descriptionTextPane.setText(tableModules.get(rowIndex).getDescription());
} else {
GeneralReportModule module = generalModules.get(rowIndex - tableModules.size());
JPanel panel = module.getConfigurationPanel();
descriptionTextPane.setText(module.getDescription());
if (panel != null) {
configurationPanel.add(panel, BorderLayout.CENTER);
}
}
configurationPanel.revalidate();
configurationPanel.repaint();
}
}
}
@@ -0,0 +1,160 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<NonVisualComponents>
<Component class="javax.swing.ButtonGroup" name="optionsButtonGroup">
</Component>
</NonVisualComponents>
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[650, 250]"/>
</Property>
</Properties>
<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" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="taggedResultsRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="allResultsRadioButton" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="dataLabel" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="481" max="32767" attributes="0"/>
</Group>
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="-2" pref="21" max="-2" attributes="0"/>
<Component id="tagsScrollPane" max="32767" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="advancedButton" alignment="1" max="32767" attributes="0"/>
<Component id="deselectAllButton" max="32767" attributes="0"/>
<Component id="selectAllButton" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
<EmptySpace 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 max="-2" attributes="0"/>
<Component id="dataLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="allResultsRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="taggedResultsRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="7" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="selectAllButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="deselectAllButton" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="70" max="32767" attributes="0"/>
</Group>
<Component id="tagsScrollPane" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="advancedButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JRadioButton" name="taggedResultsRadioButton">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="optionsButtonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportVisualPanel2.taggedResultsRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="taggedResultsRadioButtonStateChanged"/>
</Events>
</Component>
<Component class="javax.swing.JRadioButton" name="allResultsRadioButton">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="optionsButtonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportVisualPanel2.allResultsRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="dataLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportVisualPanel2.dataLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="selectAllButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportVisualPanel2.selectAllButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="selectAllButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="deselectAllButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportVisualPanel2.deselectAllButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="deselectAllButtonActionPerformed"/>
</Events>
</Component>
<Container class="javax.swing.JScrollPane" name="tagsScrollPane">
<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.JList" name="tagsList">
<Properties>
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.editors2.ListModelEditor">
<StringArray count="0"/>
</Property>
<Property name="selectionMode" type="int" value="0"/>
<Property name="layoutOrientation" type="int" value="1"/>
</Properties>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JButton" name="advancedButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/report/Bundle.properties" key="ReportVisualPanel2.advancedButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="advancedButtonActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Form>
@@ -0,0 +1,346 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2012 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.report;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
import javax.swing.ListModel;
import javax.swing.event.ListDataListener;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.Tags;
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
public final class ReportVisualPanel2 extends JPanel {
private static final Logger logger = Logger.getLogger(ReportVisualPanel2.class.getName());
private ReportWizardPanel2 wizPanel;
private Map<String, Boolean> tagStates = new LinkedHashMap<String, Boolean>();
private List<String> tags = new ArrayList<String>();
ArtifactSelectionDialog dialog = new ArtifactSelectionDialog(new JFrame(), true);
private Map<ARTIFACT_TYPE, Boolean> artifactStates = new EnumMap<ARTIFACT_TYPE, Boolean>(ARTIFACT_TYPE.class);
private List<ARTIFACT_TYPE> artifacts = new ArrayList<ARTIFACT_TYPE>();
private TagsListModel tagsModel;
private TagsListRenderer tagsRenderer;
/**
* Creates new form ReportVisualPanel2
*/
public ReportVisualPanel2(ReportWizardPanel2 wizPanel) {
initComponents();
initTags();
initArtifactTypes();
tagsList.setEnabled(false);
selectAllButton.setEnabled(false);
deselectAllButton.setEnabled(false);
allResultsRadioButton.setSelected(true);
this.wizPanel = wizPanel;
}
// Initialize the list of Tags
private void initTags() {
for(String tag : Tags.getTagNames()) {
tagStates.put(tag, Boolean.FALSE);
}
tags.addAll(tagStates.keySet());
tagsModel = new TagsListModel();
tagsRenderer = new TagsListRenderer();
tagsList.setModel(tagsModel);
tagsList.setCellRenderer(tagsRenderer);
tagsList.setVisibleRowCount(-1);
// Add the ability to enable and disable Tag checkboxes to the list
tagsList.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent evt) {
JList list = (JList) evt.getSource();
int index = list.locationToIndex(evt.getPoint());
String value = (String) tagsModel.getElementAt(index);
tagStates.put(value, !tagStates.get(value));
list.repaint();
updateFinishButton();
}
});
}
// Initialize the list of Artifacts
private void initArtifactTypes() {
artifacts = ArtifactSelectionDialog.getImportantArtifactTypes();
artifactStates = new EnumMap<ARTIFACT_TYPE, Boolean>(ARTIFACT_TYPE.class);
for (ARTIFACT_TYPE type : artifacts) {
artifactStates.put(type, Boolean.TRUE);
}
}
@Override
public String getName() {
return "Configure HTML and Excel reports";
}
/**
* @return the enabled/disabled state of all Artifacts
*/
Map<ARTIFACT_TYPE, Boolean> getArtifactStates() {
return artifactStates;
}
/**
* @return the enabled/disabled state of all Tags
*/
Map<String, Boolean> getTagStates() {
return tagStates;
}
private boolean areTagsSelected() {
boolean result = false;
for (Entry<String, Boolean> entry: tagStates.entrySet()) {
if (entry.getValue()) {
result = true;
}
}
return result;
}
private boolean areArtifactsSelected() {
boolean result = false;
for (Entry<ARTIFACT_TYPE, Boolean> entry: artifactStates.entrySet()) {
if (entry.getValue()) {
result = true;
}
}
return result;
}
private void updateFinishButton() {
if (taggedResultsRadioButton.isSelected()) {
wizPanel.setFinish(areTagsSelected());
} else {
wizPanel.setFinish(areArtifactsSelected());
}
}
/**
* @return true if the Tags radio button is selected, false otherwise
*/
boolean isTaggedResultsRadioButtonSelected() {
return taggedResultsRadioButton.isSelected();
}
/**
* 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.
*/
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
optionsButtonGroup = new javax.swing.ButtonGroup();
taggedResultsRadioButton = new javax.swing.JRadioButton();
allResultsRadioButton = new javax.swing.JRadioButton();
dataLabel = new javax.swing.JLabel();
selectAllButton = new javax.swing.JButton();
deselectAllButton = new javax.swing.JButton();
tagsScrollPane = new javax.swing.JScrollPane();
tagsList = new javax.swing.JList();
advancedButton = new javax.swing.JButton();
setPreferredSize(new java.awt.Dimension(650, 250));
optionsButtonGroup.add(taggedResultsRadioButton);
org.openide.awt.Mnemonics.setLocalizedText(taggedResultsRadioButton, org.openide.util.NbBundle.getMessage(ReportVisualPanel2.class, "ReportVisualPanel2.taggedResultsRadioButton.text")); // NOI18N
taggedResultsRadioButton.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
taggedResultsRadioButtonStateChanged(evt);
}
});
optionsButtonGroup.add(allResultsRadioButton);
org.openide.awt.Mnemonics.setLocalizedText(allResultsRadioButton, org.openide.util.NbBundle.getMessage(ReportVisualPanel2.class, "ReportVisualPanel2.allResultsRadioButton.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(dataLabel, org.openide.util.NbBundle.getMessage(ReportVisualPanel2.class, "ReportVisualPanel2.dataLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(selectAllButton, org.openide.util.NbBundle.getMessage(ReportVisualPanel2.class, "ReportVisualPanel2.selectAllButton.text")); // NOI18N
selectAllButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
selectAllButtonActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(deselectAllButton, org.openide.util.NbBundle.getMessage(ReportVisualPanel2.class, "ReportVisualPanel2.deselectAllButton.text")); // NOI18N
deselectAllButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
deselectAllButtonActionPerformed(evt);
}
});
tagsList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
tagsList.setLayoutOrientation(javax.swing.JList.VERTICAL_WRAP);
tagsScrollPane.setViewportView(tagsList);
org.openide.awt.Mnemonics.setLocalizedText(advancedButton, org.openide.util.NbBundle.getMessage(ReportVisualPanel2.class, "ReportVisualPanel2.advancedButton.text")); // NOI18N
advancedButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
advancedButtonActionPerformed(evt);
}
});
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()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(taggedResultsRadioButton)
.addComponent(allResultsRadioButton)
.addComponent(dataLabel))
.addGap(0, 481, Short.MAX_VALUE))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(21, 21, 21)
.addComponent(tagsScrollPane)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(advancedButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(deselectAllButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(selectAllButton, 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(dataLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(allResultsRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(taggedResultsRadioButton)
.addGap(7, 7, 7)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(selectAllButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(deselectAllButton)
.addGap(0, 70, Short.MAX_VALUE))
.addComponent(tagsScrollPane))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(advancedButton)
.addContainerGap())
);
}// </editor-fold>//GEN-END:initComponents
private void taggedResultsRadioButtonStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_taggedResultsRadioButtonStateChanged
tagsList.setEnabled(taggedResultsRadioButton.isSelected());
selectAllButton.setEnabled(taggedResultsRadioButton.isSelected());
deselectAllButton.setEnabled(taggedResultsRadioButton.isSelected());
advancedButton.setEnabled(!taggedResultsRadioButton.isSelected());
updateFinishButton();
}//GEN-LAST:event_taggedResultsRadioButtonStateChanged
private void selectAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectAllButtonActionPerformed
for (String tag : tags) {
tagStates.put(tag, Boolean.TRUE);
}
tagsList.repaint();
wizPanel.setFinish(true);
}//GEN-LAST:event_selectAllButtonActionPerformed
private void deselectAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deselectAllButtonActionPerformed
for (String tag : tags) {
tagStates.put(tag, Boolean.FALSE);
}
tagsList.repaint();
wizPanel.setFinish(false);
}//GEN-LAST:event_deselectAllButtonActionPerformed
private void advancedButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_advancedButtonActionPerformed
artifactStates = dialog.display();
wizPanel.setFinish(areArtifactsSelected());
}//GEN-LAST:event_advancedButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton advancedButton;
private javax.swing.JRadioButton allResultsRadioButton;
private javax.swing.JLabel dataLabel;
private javax.swing.JButton deselectAllButton;
private javax.swing.ButtonGroup optionsButtonGroup;
private javax.swing.JButton selectAllButton;
private javax.swing.JRadioButton taggedResultsRadioButton;
private javax.swing.JList tagsList;
private javax.swing.JScrollPane tagsScrollPane;
// End of variables declaration//GEN-END:variables
private class TagsListModel implements ListModel {
@Override
public int getSize() {
return tags.size();
}
@Override
public Object getElementAt(int index) {
return tags.get(index);
}
@Override
public void addListDataListener(ListDataListener l) {
}
@Override
public void removeListDataListener(ListDataListener l) {
}
}
// Render the Tags as JCheckboxes
private class TagsListRenderer extends JCheckBox implements ListCellRenderer {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
if (value != null) {
setEnabled(list.isEnabled());
setSelected(tagStates.get(value.toString()));
setFont(list.getFont());
setBackground(list.getBackground());
setForeground(list.getForeground());
setText(value.toString());
return this;
}
return new JLabel();
}
}
}
@@ -0,0 +1,163 @@
/*
*
* Autopsy Forensic Browser
*
* Copyright 2012 Basis Technology Corp.
*
* Copyright 2012 42six Solutions.
* Contact: aebadirad <at> 42six <dot> com
* Project Contact/Architect: 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.report;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.text.MessageFormat;
import java.util.Map;
import java.util.logging.Level;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import org.openide.DialogDisplayer;
import org.openide.WizardDescriptor;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionReferences;
import org.openide.awt.ActionRegistration;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.openide.util.actions.CallableSystemAction;
import org.openide.util.actions.Presenter;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.report.ReportWizardAction")
@ActionRegistration(displayName = "#CTL_ReportWizardAction", lazy = false)
@ActionReferences(value = {
@ActionReference(path = "Menu/Tools", position = 80)})
@NbBundle.Messages(value = "CTL_ReportWizardAction=Run Report")
public final class ReportWizardAction extends CallableSystemAction implements Presenter.Toolbar, ActionListener {
private static final Logger logger = Logger.getLogger(ReportWizardAction.class.getName());
private JButton toolbarButton = new JButton();
private static final String ACTION_NAME = "Generate Report";
public ReportWizardAction() {
setEnabled(false);
Case.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals(Case.CASE_CURRENT_CASE)) {
Case newCase = (Case) evt.getNewValue();
setEnabled(newCase != null);
// Make the cases' Reoports folder, if it doesn't exist
if (newCase != null) {
boolean exists = (new File(newCase.getCaseDirectory() + File.separator + "Reports")).exists();
if (!exists) {
boolean reportCreate = (new File(newCase.getCaseDirectory() + File.separator + "Reports")).mkdirs();
if (!reportCreate) {
logger.log(Level.WARNING, "Could not create Reports directory for case. It does not exist.");
}
}
}
}
}
});
// Initialize the Generate Report button
toolbarButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ReportWizardAction.this.actionPerformed(e);
}
});
}
/**
* When the Generate Report button or menu item is selected, open the reporting wizard.
* When the wizard is finished, create a ReportGenerator with the wizard information,
* and start all necessary reports.
*/
@Override
public void actionPerformed(ActionEvent e) {
// Create the wizard
WizardDescriptor wiz = new WizardDescriptor(new ReportWizardIterator());
wiz.setTitleFormat(new MessageFormat("{0} {1}"));
wiz.setTitle("Generate Report");
// When the user presses the finish button
if (DialogDisplayer.getDefault().notify(wiz) == WizardDescriptor.FINISH_OPTION) {
// Get the wizard information
Map<TableReportModule, Boolean> tableModuleStates = (Map<TableReportModule, Boolean>) wiz.getProperty("tableModuleStates");
Map<GeneralReportModule, Boolean> generalModuleStates = (Map<GeneralReportModule, Boolean>) wiz.getProperty("generalModuleStates");
// Create the generator and generate reports
ReportGenerator generator = new ReportGenerator(tableModuleStates, generalModuleStates);
if (wiz.getProperty("isTagsSelected") != null) {
if ((Boolean) wiz.getProperty("isTagsSelected")) {
generator.generateTableTagReport((Map<String, Boolean>) wiz.getProperty("tagStates"));
} else {
generator.generateTableArtifactReport((Map<ARTIFACT_TYPE, Boolean>) wiz.getProperty("artifactStates"));
}
}
generator.generateGeneralReports();
// Open the progress window for the user
generator.displayProgressPanels();
}
}
@Override
public void performAction() {
}
@Override
public String getName() {
return ACTION_NAME;
}
@Override
public HelpCtx getHelpCtx() {
return HelpCtx.DEFAULT_HELP;
}
/**
* Returns the toolbar component of this action
*
* @return component the toolbar button
*/
@Override
public Component getToolbarPresenter() {
ImageIcon icon = new ImageIcon(getClass().getResource("images/btn_icon_generate_report.png"));
toolbarButton.setIcon(icon);
toolbarButton.setText("Generate Report");
return toolbarButton;
}
/**
* Set this action to be enabled/disabled
*
* @param value whether to enable this action or not
*/
@Override
public void setEnabled(boolean value) {
super.setEnabled(value);
toolbarButton.setEnabled(value);
}
}
@@ -0,0 +1,99 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2012 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.report;
import java.awt.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import javax.swing.JComponent;
import javax.swing.event.ChangeListener;
import org.openide.WizardDescriptor;
public final class ReportWizardIterator implements WizardDescriptor.Iterator<WizardDescriptor> {
private int index;
private List<WizardDescriptor.Panel<WizardDescriptor>> panels;
private List<WizardDescriptor.Panel<WizardDescriptor>> getPanels() {
if (panels == null) {
panels = new ArrayList<WizardDescriptor.Panel<WizardDescriptor>>();
panels.add(new ReportWizardPanel1());
panels.add(new ReportWizardPanel2());
String[] steps = new String[panels.size()];
for (int i = 0; i < panels.size(); i++) {
Component c = panels.get(i).getComponent();
// Default step name to component name of panel.
steps[i] = c.getName();
if (c instanceof JComponent) { // assume Swing components
JComponent jc = (JComponent) c;
jc.putClientProperty(WizardDescriptor.PROP_CONTENT_SELECTED_INDEX, i);
jc.putClientProperty(WizardDescriptor.PROP_CONTENT_DATA, steps);
jc.putClientProperty(WizardDescriptor.PROP_AUTO_WIZARD_STYLE, true);
jc.putClientProperty(WizardDescriptor.PROP_CONTENT_DISPLAYED, false);
jc.putClientProperty(WizardDescriptor.PROP_CONTENT_NUMBERED, true);
}
}
}
return panels;
}
@Override
public WizardDescriptor.Panel<WizardDescriptor> current() {
return getPanels().get(index);
}
@Override
public String name() {
return "";
}
@Override
public boolean hasNext() {
return index < getPanels().size() - 1;
}
@Override
public boolean hasPrevious() {
return index > 0;
}
@Override
public void nextPanel() {
if (!hasNext()) {
throw new NoSuchElementException();
}
index++;
}
@Override
public void previousPanel() {
if (!hasPrevious()) {
throw new NoSuchElementException();
}
index--;
}
@Override
public void addChangeListener(ChangeListener l) {
}
@Override
public void removeChangeListener(ChangeListener l) {
}
}
@@ -0,0 +1,108 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2012 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.report;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.event.ChangeListener;
import org.openide.WizardDescriptor;
import org.openide.util.HelpCtx;
public class ReportWizardPanel1 implements WizardDescriptor.FinishablePanel<WizardDescriptor> {
private WizardDescriptor wiz;
private ReportVisualPanel1 component;
private JButton nextButton;
private JButton finishButton;
ReportWizardPanel1() {
nextButton = new JButton("Next >");
finishButton = new JButton("Finish");
finishButton.setEnabled(false);
// Initialize our custom next and finish buttons
nextButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
wiz.doNextClick();
}
});
finishButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
wiz.doFinishClick();
}
});
}
@Override
public ReportVisualPanel1 getComponent() {
if (component == null) {
component = new ReportVisualPanel1(this);
}
return component;
}
@Override
public HelpCtx getHelp() {
return HelpCtx.DEFAULT_HELP;
}
@Override
public boolean isValid() {
// Always valid, but we control the enabled state
// of our custom buttons
return true;
}
@Override
public boolean isFinishPanel() {
return true;
}
public void setNext(boolean enabled) {
nextButton.setEnabled(enabled);
}
public void setFinish(boolean enabled) {
finishButton.setEnabled(enabled);
}
@Override
public void addChangeListener(ChangeListener l) {
}
@Override
public void removeChangeListener(ChangeListener l) {
}
@Override
public void readSettings(WizardDescriptor wiz) {
// Add out custom buttons in place of the regular ones
this.wiz = wiz;
wiz.setOptions(new Object[] {WizardDescriptor.PREVIOUS_OPTION, nextButton, finishButton, WizardDescriptor.CANCEL_OPTION});
}
@Override
public void storeSettings(WizardDescriptor wiz) {
wiz.putProperty("tableModuleStates", getComponent().getTableModuleStates());
wiz.putProperty("generalModuleStates", getComponent().getGeneralModuleStates());
}
}
@@ -0,0 +1,88 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2012 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.report;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.event.ChangeListener;
import org.openide.WizardDescriptor;
import org.openide.util.HelpCtx;
public class ReportWizardPanel2 implements WizardDescriptor.Panel<WizardDescriptor> {
private ReportVisualPanel2 component;
private JButton finishButton;
private WizardDescriptor wiz;
ReportWizardPanel2() {
finishButton = new JButton("Finish");
finishButton.setEnabled(true);
finishButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
wiz.doFinishClick();
}
});
}
@Override
public ReportVisualPanel2 getComponent() {
if (component == null) {
component = new ReportVisualPanel2(this);
}
return component;
}
@Override
public HelpCtx getHelp() {
return HelpCtx.DEFAULT_HELP;
}
@Override
public boolean isValid() {
return true;
}
@Override
public void addChangeListener(ChangeListener l) {
}
@Override
public void removeChangeListener(ChangeListener l) {
}
public void setFinish(boolean enabled) {
finishButton.setEnabled(enabled);
}
@Override
public void readSettings(WizardDescriptor wiz) {
// Re-enable the normal wizard buttons
this.wiz = wiz;
wiz.setOptions(new Object[] {WizardDescriptor.PREVIOUS_OPTION, WizardDescriptor.NEXT_OPTION, finishButton, WizardDescriptor.CANCEL_OPTION});
}
@Override
public void storeSettings(WizardDescriptor wiz) {
wiz.putProperty("tagStates", getComponent().getTagStates());
wiz.putProperty("artifactStates", getComponent().getArtifactStates());
wiz.putProperty("isTagsSelected", getComponent().isTaggedResultsRadioButtonSelected());
}
}
@@ -1,592 +0,0 @@
/*
*
* Autopsy Forensic Browser
*
* Copyright 2012 Basis Technology Corp.
*
* Copyright 2012 42six Solutions.
* Contact: aebadirad <at> 42six <dot> com
* Project Contact/Architect: 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.report;
import java.awt.Desktop;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.logging.Level;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.*;
/**
* Generates an XLS report for all the Blackboard Artifacts found in the current case.
*/
public class ReportXLS implements ReportModule {
public static Workbook wb = new XSSFWorkbook();
private static String xlsPath = "";
private ReportConfiguration config;
private static ReportXLS instance = null;
private static final Logger logger = Logger.getLogger(ReportXLS.class.getName());
public ReportXLS() {
//Empty the workbook first
}
public static synchronized ReportXLS getDefault() {
if (instance == null) {
instance = new ReportXLS();
}
return instance;
}
@Override
public String generateReport(ReportConfiguration reportconfig) throws ReportModuleException {
config = reportconfig;
ReportGen reportobj = new ReportGen();
reportobj.populateReport(reportconfig);
HashMap<BlackboardArtifact, List<BlackboardAttribute>> report = reportobj.getResults();
Workbook wbtemp = new XSSFWorkbook();
int countGen = 0;
int countBookmark = 0;
int countCookie = 0;
int countHistory = 0;
int countDownload = 0;
int countRecentObjects = 0;
int countTrackPoint = 0;
int countInstalled = 0;
int countKeyword = 0;
int countHash = 0;
int countDevice = 0;
int countEmail = 0;
int countWebSearch = 0;
int countExif = 0;
int countTagFile = 0;
for (Entry<BlackboardArtifact, List<BlackboardAttribute>> entry : report.entrySet()) {
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getTypeID()) {
countGen++;
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID()) {
countBookmark++;
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID()) {
countCookie++;
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID()) {
countHistory++;
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()) {
countDownload++;
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID()) {
countRecentObjects++;
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_TRACKPOINT.getTypeID()) {
countTrackPoint++;
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID()) {
countInstalled++;
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) {
countKeyword++;
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()) {
countHash++;
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID()) {
countDevice++;
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) {
countEmail++;
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()) {
countWebSearch++;
}
if(entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF.getTypeID()){
countExif++;
}
if(entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID()){
countTagFile++;
}
}
try {
Case currentCase = Case.getCurrentCase(); // get the most updated case
SleuthkitCase skCase = currentCase.getSleuthkitCase();
String caseName = currentCase.getName();
String examiner = currentCase.getExaminer();
String number = currentCase.getNumber();
Integer imagecount = currentCase.getImageIDs().length;
Integer filesystemcount = currentCase.getRootObjectsCount();
Integer totalfiles = skCase.countFsContentType(TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG);
Integer totaldirs = skCase.countFsContentType(TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR);
DateFormat datetimeFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss");
Date date = new Date();
String datetime = datetimeFormat.format(date);
String datenotime = dateFormat.format(date);
//The first summary report page
Sheet sheetSummary = wbtemp.createSheet("Summary");
//Generate a sheet per artifact type
// Sheet sheetGen = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getDisplayName());
Sheet sheetHash = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getDisplayName());
Sheet sheetDevice = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getDisplayName());
Sheet sheetInstalled = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_INSTALLED_PROG.getDisplayName());
Sheet sheetKeyword = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getDisplayName());
// Sheet sheetTrackpoint = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_TRACKPOINT.getDisplayName());
Sheet sheetRecent = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getDisplayName());
Sheet sheetCookie = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getDisplayName());
Sheet sheetBookmark = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getDisplayName());
Sheet sheetDownload = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getDisplayName());
Sheet sheetHistory = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getDisplayName());
Sheet sheetEmail = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getDisplayName());
Sheet sheetWebSearch = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getDisplayName());
Sheet sheetExif = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF.getDisplayName());
Sheet sheetTagFile = wbtemp.createSheet(BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getDisplayName());
//Bold/underline cell style for the top header rows
CellStyle style = wbtemp.createCellStyle();
style.setBorderBottom((short) 2);
Font font = wbtemp.createFont();
font.setFontHeightInPoints((short) 14);
font.setFontName("Arial");
font.setBoldweight((short) 2);
style.setFont(font);
//create 'default' style
CellStyle defaultstyle = wbtemp.createCellStyle();
defaultstyle.setBorderBottom((short) 2);
Font defaultfont = wbtemp.createFont();
defaultfont.setFontHeightInPoints((short) 14);
defaultfont.setFontName("Arial");
defaultfont.setBoldweight((short) 2);
defaultstyle.setFont(defaultfont);
//create the rows in the worksheet for our records
//Create first row and header
// sheetGen.createRow(0);
// sheetGen.getRow(0).createCell(0).setCellValue("Name");
// sheetGen.getRow(0).createCell(1).setCellValue("Value");
// sheetGen.getRow(0).createCell(2).setCellValue("Date/Time");
sheetSummary.setDefaultColumnStyle(1, defaultstyle);
sheetSummary.createRow(0).setRowStyle(style);
sheetSummary.getRow(0).createCell(0).setCellValue("Summary Information");
sheetSummary.getRow(0).createCell(1).setCellValue(caseName);
//add some basic information
sheetSummary.createRow(1);
sheetSummary.getRow(1).createCell(0).setCellValue("Examiner");
sheetSummary.getRow(1).createCell(1).setCellValue(examiner);
sheetSummary.createRow(2);
sheetSummary.getRow(2).createCell(0).setCellValue("Number");
sheetSummary.getRow(2).createCell(1).setCellValue(number);
sheetSummary.createRow(3);
sheetSummary.getRow(3).createCell(0).setCellValue("# of Images");
sheetSummary.getRow(3).createCell(1).setCellValue(imagecount);
sheetSummary.createRow(4);
sheetSummary.getRow(4).createCell(0).setCellValue("Filesystems found");
sheetSummary.getRow(4).createCell(1).setCellValue(filesystemcount);
sheetSummary.createRow(5);
sheetSummary.getRow(5).createCell(0).setCellValue("# of Files");
sheetSummary.getRow(5).createCell(1).setCellValue(totalfiles);
sheetSummary.createRow(6);
sheetSummary.getRow(6).createCell(0).setCellValue("# of Directories");
sheetSummary.getRow(6).createCell(1).setCellValue(totaldirs);
sheetSummary.createRow(7);
sheetSummary.getRow(7).createCell(0).setCellValue("Date/Time");
sheetSummary.getRow(7).createCell(1).setCellValue(datetime);
sheetHash.setDefaultColumnStyle(1, defaultstyle);
sheetHash.createRow(0).setRowStyle(style);
sheetHash.getRow(0).createCell(0).setCellValue("Name");
sheetHash.getRow(0).createCell(1).setCellValue("Size");
sheetHash.getRow(0).createCell(2).setCellValue("Hashset Name");
sheetHash.getRow(0).createCell(3).setCellValue("Path");
sheetDevice.setDefaultColumnStyle(1, defaultstyle);
sheetDevice.createRow(0).setRowStyle(style);
sheetDevice.getRow(0).createCell(0).setCellValue("Name");
sheetDevice.getRow(0).createCell(1).setCellValue("Serial #");
sheetDevice.getRow(0).createCell(2).setCellValue("Time");
sheetDevice.getRow(0).createCell(3).setCellValue("Path");
sheetInstalled.setDefaultColumnStyle(1, defaultstyle);
sheetInstalled.createRow(0).setRowStyle(style);
sheetInstalled.getRow(0).createCell(0).setCellValue("Program Name");
sheetInstalled.getRow(0).createCell(1).setCellValue("Install Date/Time");
sheetInstalled.getRow(0).createCell(2).setCellValue("Path");
sheetKeyword.setDefaultColumnStyle(1, defaultstyle);
sheetKeyword.createRow(0).setRowStyle(style);
sheetKeyword.getRow(0).createCell(0).setCellValue("Keyword");
sheetKeyword.getRow(0).createCell(1).setCellValue("File Name");
sheetKeyword.getRow(0).createCell(2).setCellValue("Preview");
sheetKeyword.getRow(0).createCell(3).setCellValue("Keyword List");
sheetKeyword.getRow(0).createCell(4).setCellValue("Path");
sheetRecent.setDefaultColumnStyle(1, defaultstyle);
sheetRecent.createRow(0).setRowStyle(style);
sheetRecent.getRow(0).createCell(0).setCellValue("Name");
sheetRecent.getRow(0).createCell(1).setCellValue("Path");
sheetRecent.getRow(0).createCell(2).setCellValue("Related Shortcut");
sheetRecent.getRow(0).createCell(4).setCellValue("Path");
sheetCookie.setDefaultColumnStyle(1, defaultstyle);
sheetCookie.createRow(0).setRowStyle(style);
sheetCookie.getRow(0).createCell(0).setCellValue("URL");
sheetCookie.getRow(0).createCell(1).setCellValue("Date");
sheetCookie.getRow(0).createCell(2).setCellValue("Name");
sheetCookie.getRow(0).createCell(3).setCellValue("Value");
sheetCookie.getRow(0).createCell(4).setCellValue("Program");
sheetCookie.getRow(0).createCell(5).setCellValue("Path");
sheetBookmark.setDefaultColumnStyle(1, defaultstyle);
sheetBookmark.createRow(0).setRowStyle(style);
sheetBookmark.getRow(0).createCell(0).setCellValue("URL");
sheetBookmark.getRow(0).createCell(1).setCellValue("Title");
sheetBookmark.getRow(0).createCell(2).setCellValue("Program");
sheetBookmark.getRow(0).createCell(4).setCellValue("Path");
sheetDownload.setDefaultColumnStyle(1, defaultstyle);
sheetDownload.createRow(0).setRowStyle(style);
sheetDownload.getRow(0).createCell(0).setCellValue("File");
sheetDownload.getRow(0).createCell(1).setCellValue("Source");
sheetDownload.getRow(0).createCell(2).setCellValue("Time");
sheetDownload.getRow(0).createCell(3).setCellValue("Program");
sheetDownload.getRow(0).createCell(4).setCellValue("Path");
sheetHistory.setDefaultColumnStyle(1, defaultstyle);
sheetHistory.createRow(0).setRowStyle(style);
sheetHistory.getRow(0).createCell(0).setCellValue("URL");
sheetHistory.getRow(0).createCell(1).setCellValue("Date");
sheetHistory.getRow(0).createCell(2).setCellValue("Referrer");
sheetHistory.getRow(0).createCell(3).setCellValue("Title");
sheetHistory.getRow(0).createCell(4).setCellValue("Program");
sheetHistory.getRow(0).createCell(5).setCellValue("Path");
sheetEmail.setDefaultColumnStyle(1, defaultstyle);
sheetEmail.createRow(0).setRowStyle(style);
sheetEmail.getRow(0).createCell(0).setCellValue("From");
sheetEmail.getRow(0).createCell(1).setCellValue("To");
sheetEmail.getRow(0).createCell(2).setCellValue("Subject");
sheetEmail.getRow(0).createCell(3).setCellValue("Date/Time");
sheetEmail.getRow(0).createCell(4).setCellValue("Content");
sheetEmail.getRow(0).createCell(5).setCellValue("CC");
sheetEmail.getRow(0).createCell(6).setCellValue("BCC");
sheetEmail.getRow(0).createCell(7).setCellValue("Path");
sheetWebSearch.setDefaultColumnStyle(1, defaultstyle);
sheetWebSearch.createRow(0).setRowStyle(style);
sheetWebSearch.getRow(0).createCell(0).setCellValue("Program");
sheetWebSearch.getRow(0).createCell(1).setCellValue("Domain");
sheetWebSearch.getRow(0).createCell(2).setCellValue("Text");
sheetWebSearch.getRow(0).createCell(3).setCellValue("Last Accesed");
sheetWebSearch.getRow(0).createCell(4).setCellValue("Path");
sheetExif.setDefaultColumnStyle(1, defaultstyle);
sheetExif.createRow(0).setRowStyle(style);
sheetExif.getRow(0).createCell(0).setCellValue("File Name");
sheetExif.getRow(0).createCell(1).setCellValue("Date Taken");
sheetExif.getRow(0).createCell(2).setCellValue("Device Manufacturer");
sheetExif.getRow(0).createCell(3).setCellValue("Device Model");
sheetExif.getRow(0).createCell(4).setCellValue("Latitude");
sheetExif.getRow(0).createCell(5).setCellValue("Longitude");
sheetExif.getRow(0).createCell(6).setCellValue("Altitude");
sheetExif.getRow(0).createCell(7).setCellValue("Path");
sheetTagFile.setDefaultColumnStyle(1, defaultstyle);
sheetTagFile.createRow(0).setRowStyle(style);
sheetTagFile.getRow(0).createCell(0).setCellValue("Comment");
sheetTagFile.getRow(0).createCell(1).setCellValue("File Name");
sheetTagFile.getRow(0).createCell(2).setCellValue("Path");
for (int i = 0; i < wbtemp.getNumberOfSheets(); i++) {
Sheet tempsheet = wbtemp.getSheetAt(i);
tempsheet.setAutobreaks(true);
for (Row temprow : tempsheet) {
for (Cell cell : temprow) {
cell.setCellStyle(style);
tempsheet.autoSizeColumn(cell.getColumnIndex());
}
}
}
int countedGen = 0;
int countedBookmark = 0;
int countedCookie = 0;
int countedHistory = 0;
int countedDownload = 0;
int countedRecentObjects = 0;
int countedTrackPoint = 0;
int countedInstalled = 0;
int countedKeyword = 0;
int countedHash = 0;
int countedDevice = 0;
int countedEmail = 0;
int countedWebSearch = 0;
int countedExif = 0;
int countedTagFile = 0;
//start populating the sheets in the workbook
for (Entry<BlackboardArtifact, List<BlackboardAttribute>> entry : report.entrySet()) {
if (ReportFilter.cancel == true) {
break;
}
int cc = 0;
Long objId = entry.getKey().getObjectID();
AbstractFile file = skCase.getAbstractFileById(objId);
String filename = file.getName();
Long filesize = file.getSize();
TreeMap<Integer, String> attributes = new TreeMap<Integer, String>();
// Get all the attributes, line them up to be added. Place empty string placeholders for each attribute type
int n;
for (n = 1; n <= 36; n++) {
attributes.put(n, "");
}
for (BlackboardAttribute tempatt : entry.getValue()) {
if (ReportFilter.cancel == true) {
break;
}
String value = "";
int type = tempatt.getAttributeTypeID();
if (tempatt.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_RCVD.getTypeID() || tempatt.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID() || tempatt.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()) {
value = new java.text.SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(new java.util.Date((tempatt.getValueLong()) * 1000)).toString();
} else {
value = tempatt.getValueString();
}
// attributes.put(type, StringEscapeUtils.escapeCsv(value));
attributes.put(type, value);
cc++;
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getTypeID()) {
countedGen++;
// Row temp = sheetGen.getRow(countedGen);
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID()) {
countedBookmark++;
Row temp = sheetBookmark.createRow(countedBookmark);
temp.createCell(0).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL.getTypeID()));
temp.createCell(1).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME.getTypeID()));
temp.createCell(2).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
temp.createCell(3).setCellValue(file.getUniquePath());
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID()) {
countedCookie++;
Row temp = sheetCookie.createRow(countedCookie);
temp.createCell(0).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL.getTypeID()));
temp.createCell(1).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
temp.createCell(2).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME.getTypeID()));
temp.createCell(3).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_VALUE.getTypeID()));
temp.createCell(4).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
temp.createCell(5).setCellValue(file.getUniquePath());
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID()) {
countedHistory++;
Row temp = sheetHistory.createRow(countedHistory);
temp.createCell(0).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL.getTypeID()));
temp.createCell(1).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()));
temp.createCell(2).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_REFERRER.getTypeID()));
temp.createCell(3).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME.getTypeID()));
temp.createCell(4).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
temp.createCell(5).setCellValue(file.getUniquePath());
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()) {
countedDownload++;
Row temp = sheetDownload.createRow(countedDownload);
temp.createCell(0).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH.getTypeID()));
temp.createCell(1).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL.getTypeID()));
temp.createCell(2).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()));
temp.createCell(3).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
temp.createCell(4).setCellValue(file.getUniquePath());
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID()) {
countedRecentObjects++;
Row temp = sheetRecent.createRow(countedRecentObjects);
temp.createCell(0).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME.getTypeID()));
temp.createCell(1).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH.getTypeID()));
temp.createCell(2).setCellValue(file.getName());
temp.createCell(3).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
temp.createCell(4).setCellValue(file.getUniquePath());
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_TRACKPOINT.getTypeID()) {
// sheetTrackpoint.addContent(artifact);
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID()) {
countedInstalled++;
Row temp = sheetInstalled.createRow(countedInstalled);
temp.createCell(0).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
temp.createCell(1).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
temp.createCell(2).setCellValue(file.getUniquePath());
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) {
countedKeyword++;
Row temp = sheetKeyword.createRow(countedKeyword);
temp.createCell(0).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID()));
temp.createCell(1).setCellValue(filename);
temp.createCell(2).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW.getTypeID()));
temp.createCell(3).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()));
temp.createCell(4).setCellValue(file.getUniquePath());
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()) {
countedHash++;
Row temp = sheetHash.createRow(countedHash);
temp.createCell(0).setCellValue(file.getName().toString());
temp.createCell(1).setCellValue(filesize.toString());
temp.createCell(2).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID()));
temp.createCell(3).setCellValue(file.getUniquePath());
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID()) {
countedDevice++;
Row temp = sheetDevice.createRow(countedDevice);
temp.createCell(0).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MODEL.getTypeID()));
temp.createCell(1).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID.getTypeID()));
temp.createCell(2).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
temp.createCell(3).setCellValue(file.getUniquePath());
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) {
countedEmail++;
Row temp = sheetEmail.createRow(countedEmail);
temp.createCell(0).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_FROM.getTypeID()));
temp.createCell(1).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_TO.getTypeID()));
temp.createCell(2).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SUBJECT.getTypeID()));
temp.createCell(3).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_RCVD.getTypeID()));
temp.createCell(4).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CONTENT_PLAIN.getTypeID()));
temp.createCell(5).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_CC.getTypeID()));
temp.createCell(6).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL_BCC.getTypeID()));
temp.createCell(7).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH.getTypeID()));
temp.createCell(8).setCellValue(file.getUniquePath());
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()) {
countedWebSearch++;
Row temp = sheetWebSearch.createRow(countedWebSearch);
temp.createCell(0).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID()));
temp.createCell(1).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID()));
temp.createCell(2).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT.getTypeID()));
temp.createCell(3).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED.getTypeID()));
temp.createCell(4).setCellValue(file.getUniquePath());
}
if(entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF.getTypeID()){
countedExif++;
Row temp = sheetExif.createRow(countedExif);
temp.createCell(0).setCellValue(file.getName());
temp.createCell(1).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID()));
temp.createCell(2).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MAKE.getTypeID()));
temp.createCell(3).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MODEL.getTypeID()));
temp.createCell(4).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE.getTypeID()));
temp.createCell(5).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE.getTypeID()));
temp.createCell(6).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE.getTypeID()));
temp.createCell(7).setCellValue(file.getUniquePath());
}
if(entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID()){
countedTagFile++;
Row temp = sheetTagFile.createRow(countedTagFile);
temp.createCell(0).setCellValue(attributes.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT.getTypeID()));
temp.createCell(1).setCellValue(file.getName());
temp.createCell(2).setCellValue(file.getUniquePath());
}
}
//write out the report to the reports folder, set the wbtemp to the primary wb object
wb = wbtemp;
xlsPath = currentCase.getCaseDirectory() + File.separator + "Reports" + File.separator + caseName + "-" + datenotime + ".xlsx";
this.save(xlsPath);
} catch (TskCoreException tce) {
logger.log(Level.WARNING, "Could not create XLS report", tce);
}
return xlsPath;
}
@Override
public void save(String path) {
try {
FileOutputStream fos = new FileOutputStream(path);
wb.write(fos);
fos.close();
} catch (IOException e) {
logger.log(Level.WARNING, "Could not write out XLS report!", e);
}
}
@Override
public String getName() {
String name = "Excel";
return name;
}
@Override
public String getReportType() {
String type = "XLS";
return type;
}
@Override
public String getExtension() {
String ext = ".xlsx";
return ext;
}
@Override
public ReportConfiguration GetReportConfiguration() {
return config;
}
@Override
public String getReportTypeDescription() {
String desc = "This is an xls formatted report that is meant to be viewed in Excel.";
return desc;
}
@Override
public void getPreview(String path) {
File file = new File(path);
try {
Desktop.getDesktop().open(file);
} catch (IOException e) {
logger.log(Level.WARNING, "Could not open XLS report! ", e);
}
}
}
@@ -1,314 +0,0 @@
/*
*
* Autopsy Forensic Browser
*
* Copyright 2012 Basis Technology Corp.
*
* Copyright 2012 42six Solutions.
* Contact: aebadirad <at> 42six <dot> com
* Project Contact/Architect: 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.report;
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.regex.Pattern;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.XMLUtil;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.datamodel.*;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
* Generates an XML report for all the Blackboard Artifacts found in the current case.
*/
public class ReportXML implements ReportModule {
public static Document xmldoc;
private ReportConfiguration reportconfig;
private String xmlPath;
private static ReportXML instance = null;
private static final Logger logger = Logger.getLogger(ReportXML.class.getName());
public ReportXML() {
}
public static synchronized ReportXML getDefault() {
if (instance == null) {
instance = new ReportXML();
}
return instance;
}
@Override
public String generateReport(ReportConfiguration reportconfig) throws ReportModuleException {
ReportGen reportobj = new ReportGen();
reportobj.populateReport(reportconfig);
HashMap<BlackboardArtifact, List<BlackboardAttribute>> report = reportobj.getResults();
try {
Case currentCase = Case.getCurrentCase(); // get the most updated case
SleuthkitCase skCase = currentCase.getSleuthkitCase();
String caseName = currentCase.getName();
String examiner = currentCase.getExaminer();
String number = currentCase.getNumber();
Integer imagecount = currentCase.getImageIDs().length;
Integer filesystemcount = currentCase.getRootObjectsCount();
Integer totalfiles = skCase.countFsContentType(TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG);
Integer totaldirs = skCase.countFsContentType(TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR);
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document ret = builder.newDocument();
Element root = ret.createElement("Case");
DateFormat datetimeFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss");
Date date = new Date();
String datetime = datetimeFormat.format(date);
String datenotime = dateFormat.format(date);
Comment comment = ret.createComment("XML Report Generated by Autopsy 3 on " + datetime);
root.appendChild(comment);
//Create summary node involving how many of each type
Element summary = ret.createElement("Summary");
if (IngestManager.getDefault().isIngestRunning()) {
Element warning = ret.createElement("Warning");
warning.setTextContent("Report was run before ingest services completed!");
summary.appendChild(warning);
}
Element name = ret.createElement("Name");
name.setTextContent(caseName);
summary.appendChild(name);
Element texaminer = ret.createElement("Examiner");
texaminer.setTextContent(examiner);
summary.appendChild(texaminer);
Element tnumber = ret.createElement("Number");
tnumber.setTextContent(number);
summary.appendChild(tnumber);
Element timages = ret.createElement("Total-Images");
timages.setTextContent(imagecount.toString());
summary.appendChild(timages);
Element tfilesys = ret.createElement("Total-FileSystems");
tfilesys.setTextContent(filesystemcount.toString());
summary.appendChild(tfilesys);
Element tfiles = ret.createElement("Total-Files");
tfiles.setTextContent(totalfiles.toString());
summary.appendChild(tfiles);
Element tdir = ret.createElement("Total-Directories");
tdir.setTextContent(totaldirs.toString());
summary.appendChild(tdir);
root.appendChild(summary);
//generate the nodes for each of the types so we can use them later
Element nodeGen = ret.createElement("General-Information");
Element nodeWebBookmark = ret.createElement("Web-Bookmarks");
Element nodeWebCookie = ret.createElement("Web-Cookies");
Element nodeWebHistory = ret.createElement("Web-History");
Element nodeWebDownload = ret.createElement("Web-Downloads");
Element nodeRecentObjects =ret.createElement("Recent-Documents");
Element nodeTrackPoint = ret.createElement("Track-Points");
Element nodeInstalled = ret.createElement("Installed-Programfiles");
Element nodeKeyword = ret.createElement("Keyword-Search-Hits");
Element nodeHash = ret.createElement("Hashset-Hits");
Element nodeDevice = ret.createElement("Attached-Devices");
Element nodeEmail = ret.createElement("Email-Messages");
Element nodeWebSearch = ret.createElement("Web-Search-Queries");
Element nodeExif = ret.createElement("Exif-Metadata");
Element nodeTagFile = ret.createElement("File-Tags");
//remove bytes
Pattern INVALID_XML_CHARS = Pattern.compile("[^\\u0009\\u000A\\u000D\\u0020-\\uD7FF\\uE000-\\uFFFD\uD800\uDC00-\uDBFF\uDFFF]");
for (Entry<BlackboardArtifact, List<BlackboardAttribute>> entry : report.entrySet()) {
if (ReportFilter.cancel == true) {
break;
}
int cc = 0;
Element artifact = ret.createElement("Artifact");
Long objId = entry.getKey().getObjectID();
Content cont = skCase.getContentById(objId);
Long filesize = cont.getSize();
try {
artifact.setAttribute("ID", objId.toString());
artifact.setAttribute("Name", cont.getName());
artifact.setAttribute("Size", filesize.toString());
} catch (Exception e) {
logger.log(Level.WARNING, "Visitor content exception occurred:", e);
}
// Get all the attributes for this guy
for (BlackboardAttribute tempatt : entry.getValue()) {
if (ReportFilter.cancel == true) {
break;
}
Element attribute = ret.createElement("Attribute");
attribute.setAttribute("Type", tempatt.getAttributeTypeDisplayName());
String tempvalue = tempatt.getValueString();
//INVALID_XML_CHARS.matcher(tempvalue).replaceAll("");
Element value = ret.createElement("Value");
value.setTextContent(tempvalue);
Element context = ret.createElement("Context");
context.setTextContent(tempatt.getContext());
Element path = ret.createElement("Path");
String pathStr = skCase.getAbstractFileById(entry.getKey().getObjectID()).getUniquePath();
path.setTextContent(pathStr);
attribute.appendChild(value);
attribute.appendChild(context);
artifact.appendChild(attribute);
artifact.appendChild(path);
cc++;
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO.getTypeID()) {
nodeGen.appendChild(artifact);
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID()) {
nodeWebBookmark.appendChild(artifact);
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID()) {
nodeWebCookie.appendChild(artifact);
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID()) {
nodeWebHistory.appendChild(artifact);
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()) {
nodeWebDownload.appendChild(artifact);
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID()) {
nodeRecentObjects.appendChild(artifact);
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_TRACKPOINT.getTypeID()) {
nodeTrackPoint.appendChild(artifact);
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_INSTALLED_PROG.getTypeID()) {
nodeInstalled.appendChild(artifact);
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID()) {
nodeKeyword.appendChild(artifact);
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()) {
nodeHash.appendChild(artifact);
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID()) {
nodeDevice.appendChild(artifact);
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID()) {
nodeEmail.appendChild(artifact);
}
if (entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID()) {
nodeWebSearch.appendChild(artifact);
}
if(entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF.getTypeID()){
nodeExif.appendChild(artifact);
}
if(entry.getKey().getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID()){
nodeTagFile.appendChild(artifact);
}
//end of master loop
}
//add them in the order we want them to the document
root.appendChild(nodeGen);
root.appendChild(nodeWebBookmark);
root.appendChild(nodeWebCookie);
root.appendChild(nodeWebHistory);
root.appendChild(nodeWebDownload);
root.appendChild(nodeRecentObjects);
root.appendChild(nodeTrackPoint);
root.appendChild(nodeInstalled);
root.appendChild(nodeKeyword);
root.appendChild(nodeHash);
root.appendChild(nodeDevice);
root.appendChild(nodeEmail);
root.appendChild(nodeWebSearch);
root.appendChild(nodeExif);
root.appendChild(nodeTagFile);
ret.appendChild(root);
xmldoc = ret;
//Export it the first time
xmlPath = currentCase.getCaseDirectory() + File.separator + "Reports" + File.separator + caseName + "-" + datenotime + ".xml";
this.save(xmlPath);
} catch (TskCoreException tce) {
logger.log(Level.WARNING, "Exception occurred", tce);
}
catch(ParserConfigurationException pce){
logger.log(Level.WARNING, "Could not create XML parser", pce);
}
return xmlPath;
}
@Override
public void save(String path) {
XMLUtil.saveDoc(ReportXML.class, xmlPath, "UTF-8", xmldoc);
}
@Override
public String getName() {
String name = "Default XML";
return name;
}
@Override
public String getReportType() {
String type = "XML";
return type;
}
@Override
public String getExtension() {
String ext = ".xml";
return ext;
}
@Override
public ReportConfiguration GetReportConfiguration() {
ReportConfiguration config = reportconfig;
return config;
}
@Override
public void getPreview(String path) {
BrowserControl.openUrl(path);
}
@Override
public String getReportTypeDescription() {
String desc = "This is an xml formatted report that is meant to be viewed in a modern browser.";
return desc;
}
}
@@ -0,0 +1,122 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2012 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.report;
import java.util.List;
/**
* ReportModule that implements a tabular style of reporting.
*
* All TableReportModules will be sent the exact data to report, and will only
* have to determine how to write and display this data.
*
* The data sent consists of user-chosen fields such as Blackboard Artifacts
* and File/Result Tags.
*/
public interface TableReportModule extends ReportModule {
/**
* Start the report. Open any output streams, initialize member variables,
* write summary and navigation pages. Considered the "constructor" of the report.
*
* @param path String path to save the report
*/
public void startReport(String path);
/**
* End the report. Close all output streams and write any end-of-report
* files.
*/
public void endReport();
/**
* Start a new data type for the report. This is how the report will differentiate between
* the start and end of a certain type of data, such as a Blackboard Artifact Type.
* It is up to the report how the differentiation is shown.
*
* @param title String name of the data type
*/
public void startDataType(String title);
/**
* End the current data type and prepare for either the end of the report
* or the start of a new data type.
*/
public void endDataType();
/**
* Start a new set, or sub-category, for the current data type.
*
* @param setName String name of the set
*/
public void startSet(String setName);
/**
* End the current set and prepare for either the end of the current data type
* or the start of a new set.
*/
public void endSet();
/**
* Add an index of all the sets to the report's current data type. This method
* is guaranteed to be called before any sets are added to the data type,
* and may be ignored.
*
* @param sets List of all the String set names
*/
public void addSetIndex(List<String> sets);
/**
* Add an element to the current set. An element is considered the 'title' of a
* table in a set, a sub-set in a sense.
*
* @param elementName String name of element
*/
public void addSetElement(String elementName);
/**
* Create a table with the column names given.
*
* @param titles List of String column names
*/
public void startTable(List<String> titles);
/**
* End the current table.
*/
public void endTable();
/**
* Add a row with the cell values given to the current table.
*
* @param row List of String cell values
*/
public void addRow(List<String> row);
/**
* Returns a String date, created by the module. All date values will query
* the module for it's interpretation of the date before sending it a row
* with the date value.
*
* @param date long date as long
* @return String date as String
*/
public String dateToString(long date);
}

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Before

Width:  |  Height:  |  Size: 662 B

After

Width:  |  Height:  |  Size: 662 B

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 672 B

After

Width:  |  Height:  |  Size: 672 B

Before

Width:  |  Height:  |  Size: 284 KiB

After

Width:  |  Height:  |  Size: 284 KiB

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 877 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 577 B

Before

Width:  |  Height:  |  Size: 783 B

After

Width:  |  Height:  |  Size: 783 B

Before

Width:  |  Height:  |  Size: 290 B

After

Width:  |  Height:  |  Size: 290 B

Before

Width:  |  Height:  |  Size: 559 B

After

Width:  |  Height:  |  Size: 559 B

@@ -1,7 +1,7 @@
/**
\package org.sleuthkit.autopsy.report
This package provides the reporting framework. Reporting modules allow you to get output from Autopsy in the form of XML, HTML, etc.
This package provides the reporting framework. Reporting modules allow you to get output from Autopsy in the form of an HTML webpage, an Excel document, etc.
Refer to \ref mod_report_page for details on building a report module.
+3
View File
@@ -1,8 +1,11 @@
---------------- VERSION Current (dev) --------------
New features:
- Documented report module API
Improvements:
- Remake of reporting UI and functionality
- Significant increase in reporting speed
Bugfixes:
+76 -6
View File
@@ -1,12 +1,82 @@
/*! \page mod_report_page Developing Report Modules
\section report_summary Summary
There are two types of reporting modules: table report modules and general report modules.
<!-- @@@ Cleanup -->
Each reporting submodule implements org.sleuthkit.autopsy.report.ReportModule interface and registers itself in layer.xml
Each reporting submodule implements either the org.sleuthkit.autopsy.report.TableReportModule interface or the org.sleuthkit.autopsy.report.GeneralReportModule interface, and registers itself in layer.xml
Reporting submodule typically interacts with 3 components:
- org.sleuthkit.autopsy.report.ReportConfiguration - to read current reporting configuration set by the user,
- Blackboard API in org.sleuthkit.datamodel.SleuthkitCase class - to traverse and read blackboard artifacts and attributes,
- an API (possibly external/thirdparty API) to convert blackboard artifacts data structures to the desired reporting format.
Implementing either of those interfaces will require the reporting module to implement a number of abstract methods. And depending on the type of report module, different methods will be invoked by the application.
Table report modules require their sub-classes to override methods to start and end tables, and add rows to those tables. These methods are provided data, generated from a default configuration panel, for the module to report on. Because of this, when creating a table report module one only needs to focus on how to display the data, not how to find it.
On the other hand, general report modules have a single method to generate the report. This method gives the module freedom to find and process any data it so chooses. General modules also have the ability to provide a configuration panel, allowing the user to choose from various displayed settings. The report module may then use the user's selection to generate a more specific report.
General modules are also given the responsibility of updating their report's progress bar and processing label in the UI. A progress panel is given to every general report module. It contains basic API to start, stop, and add to the progress bar, as well as update the processing label. The module is also expeted to check the progress bar's status occasionally to see if the user has manually canceled the report.
\section report_create_module Creating a Report Module
To create a table report module, start off by creating a class and implementing either the TableReportModule interface or the GeneralReportModule interface.
\subsection report_create_module_table Table Report Modules
If you implement TableReportModule, you should override the methods:
- org.sleuthkit.autopsy.report.TableReportModule::startReport(String path)
- org.sleuthkit.autopsy.report.TableReportModule::endReport()
- org.sleuthkit.autopsy.report.TableReportModule::startDataType(String title)
- org.sleuthkit.autopsy.report.TableReportModule::endDataType()
- org.sleuthkit.autopsy.report.TableReportModule::startSet(String setName)
- org.sleuthkit.autopsy.report.TableReportModule::endSet()
- org.sleuthkit.autopsy.report.TableReportModule::addSetIndex(List<String> sets)
- org.sleuthkit.autopsy.report.TableReportModule::addSetElement(String elementName)
- org.sleuthkit.autopsy.report.TableReportModule::startTable(List<String> titles)
- org.sleuthkit.autopsy.report.TableReportModule::endTable()
- org.sleuthkit.autopsy.report.TableReportModule::addRow(List<String> row)
- org.sleuthkit.autopsy.report.TableReportModule::dateToString(long date)
When generating table module reports, Autopsy will iterate through a list of user selected data, and call methods such as addRow(List<String> row) for every "row" of data it finds, or startTable(List<String> titles) for every new category it finds. Developers are guarenteed that every start of a data type, set, or table will be followed by an approptiate end. The focus for a table report module should be to take the given information and display it in a user friendly format. See org.sleuthkit.autopsy.report.ReportExcel for an example.
\subsection report_create_module_general General Report Modules
If you implement GeneralReportModule, the overriden methods will be:
- org.sleuthkit.autopsy.report.GeneralReportModule::generateReport(String reportPath, ReportProgressPanel progressPanel)
- org.sleuthkit.autopsy.report.GeneralReportModule::getConfigurationPanel()
For general report modules, Autopsy will simply call the generateReport(String reportPath, ReportProgressPanel progressPanel) method and leave it up to the module to aquire and report data in its desired format. The only requirements are that the module saves to the given report path and updates the org.sleuthkit.autopsy.report.ReportProgressPanel as the report progresses.
When updating the progress panel, it is recommened to update it as infrequently as possible, while still keeping the user informed. If your report processes 100,000 files and you chose to update the UI each time a file is reviewed, the UI would freeze when trying to process all your requests. This would cause problems to not only your reporting module, but to other modules running in parellel. A safer approach would be to update the UI every 1,000 files, or when a certain "category" of the files being processed has changed. For example, the HTML report module increments the progress bar and changes the processing label every time a new Blackboard Artifact Type is being processed.
Autopsy will also display the panel returned by getConfigurationPanel() in the generate report wizard, when that particular report module is selected. If null is returned, a blank panel will be displayed instead. This panel can be used to allow the user custom controls over the report.
Typically a general report module should interact with both the Blackboard API in the org.sleuthkit.datamodel.SleuthkitCase class, in addition to an API (possibly external/thirdparty) to convert Blackboard Artifacts to the desired reporting format.
\subsection report_create_module_layer Registering the Report in layer.xml
Lastly, it is important to register each report module, regardless of the type, to a layer.xml file. This file serves as a globally excessible instance of the report module, and allows all report modules to be recognized abstractly without knowing each class. Without this file, Autopsy will be unable to see your report module.
An example entry into layer.xml is shown below:
\code
<folder name="Services">
<file name="org-sleuthkit-autopsy-report-ReportHTML.instance">
<attr name="instanceOf" stringvalue="org.sleuthkit.autopsy.report.TableReportModule"/>
<attr name="instanceCreate" methodvalue="org.sleuthkit.autopsy.report.ReportHTML.getDefault"/>
<attr name="position" intvalue="910"/>
</file>
</folder>
\endcode
In the above example, "org-sleuthkit-autopsy-report-ReportHTML" should be replaced with the package based path to your report module.
It is also important to remember to include a getDefault() method in your report module. As shown in the code above, the instance to each report module is accessed via it's getDefault() method.
\code
// Static instance of this report
private static MyReport instance;
// Get the default instance of this report
public static synchronized MyReport getDefault() {
if (instance == null) {
instance = new MyReport();
}
return instance;
}
\endcode
Above is an example implementation of the getDefault() method.
*/