Merge branch 'develop' into python_sample_updates

This commit is contained in:
Brian Carrier 2015-08-12 10:58:34 -04:00
commit ee4a44661e
500 changed files with 10886 additions and 9603 deletions

View File

@ -31,12 +31,14 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.TskCoreException;
/**
* Instances of this Action allow users to apply tags to blackboard artifacts.
* Instances of this Action allow users to apply tags to blackboard artifacts.
*/
public class AddBlackboardArtifactTagAction extends AddTagAction {
// This class is a singleton to support multi-selection of nodes, since
// org.openide.nodes.NodeOp.findActions(Node[] nodes) will only pick up an Action if every
// node in the array returns a reference to the same action object from Node.getActions(boolean).
private static AddBlackboardArtifactTagAction instance;
public static synchronized AddBlackboardArtifactTagAction getInstance() {
@ -49,13 +51,13 @@ public class AddBlackboardArtifactTagAction extends AddTagAction {
private AddBlackboardArtifactTagAction() {
super("");
}
@Override
protected String getActionDisplayName() {
String singularTagResult = NbBundle.getMessage(this.getClass(),
"AddBlackboardArtifactTagAction.singularTagResult");
"AddBlackboardArtifactTagAction.singularTagResult");
String pluralTagResult = NbBundle.getMessage(this.getClass(),
"AddBlackboardArtifactTagAction.pluralTagResult");
"AddBlackboardArtifactTagAction.pluralTagResult");
return Utilities.actionsGlobalContext().lookupAll(BlackboardArtifact.class).size() > 1 ? pluralTagResult : singularTagResult;
}
@ -65,17 +67,16 @@ public class AddBlackboardArtifactTagAction extends AddTagAction {
for (BlackboardArtifact artifact : selectedArtifacts) {
try {
Case.getCurrentCase().getServices().getTagsManager().addBlackboardArtifactTag(artifact, tagName, comment);
}
catch (TskCoreException ex) {
} catch (TskCoreException ex) {
Logger.getLogger(AddBlackboardArtifactTagAction.class.getName()).log(Level.SEVERE, "Error tagging result", ex); //NON-NLS
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(this.getClass(),
"AddBlackboardArtifactTagAction.unableToTag.msg",
artifact.getDisplayName()),
NbBundle.getMessage(this.getClass(),
"AddBlackboardArtifactTagAction.taggingErr"),
JOptionPane.ERROR_MESSAGE);
}
}
}
NbBundle.getMessage(this.getClass(),
"AddBlackboardArtifactTagAction.unableToTag.msg",
artifact.getDisplayName()),
NbBundle.getMessage(this.getClass(),
"AddBlackboardArtifactTagAction.taggingErr"),
JOptionPane.ERROR_MESSAGE);
}
}
}
}

View File

@ -31,12 +31,14 @@ import org.sleuthkit.datamodel.BlackboardArtifactTag;
import org.sleuthkit.datamodel.TskCoreException;
/**
* Instances of this Action allow users to delete tags applied to blackboard artifacts.
* Instances of this Action allow users to delete tags applied to blackboard
* artifacts.
*/
public class DeleteBlackboardArtifactTagAction extends AbstractAction {
private static final String MENU_TEXT = NbBundle.getMessage(DeleteBlackboardArtifactTagAction.class,
"DeleteBlackboardArtifactTagAction.deleteTags");
"DeleteBlackboardArtifactTagAction.deleteTags");
// This class is a singleton to support multi-selection of nodes, since
// org.openide.nodes.NodeOp.findActions(Node[] nodes) will only pick up an Action if every
// node in the array returns a reference to the same action object from Node.getActions(boolean).
@ -51,26 +53,24 @@ public class DeleteBlackboardArtifactTagAction extends AbstractAction {
private DeleteBlackboardArtifactTagAction() {
super(MENU_TEXT);
}
}
@Override
public void actionPerformed(ActionEvent event) {
Collection<? extends BlackboardArtifactTag> selectedTags = Utilities.actionsGlobalContext().lookupAll(BlackboardArtifactTag.class);
for (BlackboardArtifactTag tag : selectedTags) {
try {
Case.getCurrentCase().getServices().getTagsManager().deleteBlackboardArtifactTag(tag);
}
catch (TskCoreException ex) {
} catch (TskCoreException ex) {
Logger.getLogger(AddContentTagAction.class.getName()).log(Level.SEVERE, "Error deleting tag", ex); //NON-NLS
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(this.getClass(),
"DeleteBlackboardArtifactTagAction.unableToDelTag.msg",
tag.getName()),
NbBundle.getMessage(this.getClass(),
"DeleteBlackboardArtifactTagAction.tagDelErr"),
JOptionPane.ERROR_MESSAGE);
}
}
}
}
NbBundle.getMessage(this.getClass(),
"DeleteBlackboardArtifactTagAction.unableToDelTag.msg",
tag.getName()),
NbBundle.getMessage(this.getClass(),
"DeleteBlackboardArtifactTagAction.tagDelErr"),
JOptionPane.ERROR_MESSAGE);
}
}
}
}

View File

@ -31,12 +31,13 @@ import org.sleuthkit.datamodel.ContentTag;
import org.sleuthkit.datamodel.TskCoreException;
/**
* Instances of this Action allow users to delete tags applied to content.
* Instances of this Action allow users to delete tags applied to content.
*/
public class DeleteContentTagAction extends AbstractAction {
private static final String MENU_TEXT = NbBundle.getMessage(DeleteContentTagAction.class,
"DeleteContentTagAction.deleteTags");
"DeleteContentTagAction.deleteTags");
// This class is a singleton to support multi-selection of nodes, since
// org.openide.nodes.NodeOp.findActions(Node[] nodes) will only pick up an Action if every
// node in the array returns a reference to the same action object from Node.getActions(boolean).
@ -51,24 +52,23 @@ public class DeleteContentTagAction extends AbstractAction {
private DeleteContentTagAction() {
super(MENU_TEXT);
}
}
@Override
public void actionPerformed(ActionEvent e) {
Collection<? extends ContentTag> selectedTags = Utilities.actionsGlobalContext().lookupAll(ContentTag.class);
for (ContentTag tag : selectedTags) {
try {
Case.getCurrentCase().getServices().getTagsManager().deleteContentTag(tag);
}
catch (TskCoreException ex) {
} catch (TskCoreException ex) {
Logger.getLogger(AddContentTagAction.class.getName()).log(Level.SEVERE, "Error deleting tag", ex); //NON-NLS
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(this.getClass(),
"DeleteContentTagAction.unableToDelTag.msg",
tag.getName()),
NbBundle.getMessage(this.getClass(), "DeleteContentTagAction.tagDelErr"),
JOptionPane.ERROR_MESSAGE);
}
}
}
NbBundle.getMessage(this.getClass(),
"DeleteContentTagAction.unableToDelTag.msg",
tag.getName()),
NbBundle.getMessage(this.getClass(), "DeleteContentTagAction.tagDelErr"),
JOptionPane.ERROR_MESSAGE);
}
}
}
}

View File

@ -40,12 +40,14 @@ import org.sleuthkit.datamodel.TagName;
import org.sleuthkit.datamodel.TskCoreException;
public class GetTagNameAndCommentDialog extends JDialog {
private static final String NO_TAG_NAMES_MESSAGE = NbBundle.getMessage(GetTagNameAndCommentDialog.class,
"GetTagNameAndCommentDialog.noTags");
"GetTagNameAndCommentDialog.noTags");
private final HashMap<String, TagName> tagNames = new HashMap<>();
private TagNameAndComment tagNameAndComment = null;
public static class TagNameAndComment {
private TagName tagName;
private String comment;
@ -53,7 +55,7 @@ public class GetTagNameAndCommentDialog extends JDialog {
this.tagName = tagName;
this.comment = comment;
}
public TagName getTagName() {
return tagName;
}
@ -62,16 +64,16 @@ public class GetTagNameAndCommentDialog extends JDialog {
return comment;
}
}
public static TagNameAndComment doDialog() {
GetTagNameAndCommentDialog dialog = new GetTagNameAndCommentDialog();
return dialog.tagNameAndComment;
}
private GetTagNameAndCommentDialog() {
super((JFrame)WindowManager.getDefault().getMainWindow(),
NbBundle.getMessage(GetTagNameAndCommentDialog.class, "GetTagNameAndCommentDialog.createTag"),
true);
super((JFrame) WindowManager.getDefault().getMainWindow(),
NbBundle.getMessage(GetTagNameAndCommentDialog.class, "GetTagNameAndCommentDialog.createTag"),
true);
initComponents();
// Set up the dialog to close when Esc is pressed.
@ -85,32 +87,30 @@ public class GetTagNameAndCommentDialog extends JDialog {
dispose();
}
});
// Populate the combo box with the available tag names and save the
// tag name DTOs to be enable to return the one the user selects.
TagsManager tagsManager = Case.getCurrentCase().getServices().getTagsManager();
List<TagName> currentTagNames = null;
try {
currentTagNames = tagsManager.getAllTagNames();
}
catch (TskCoreException ex) {
currentTagNames = tagsManager.getAllTagNames();
} catch (TskCoreException ex) {
Logger.getLogger(GetTagNameAndCommentDialog.class.getName()).log(Level.SEVERE, "Failed to get tag names", ex); //NON-NLS
}
}
if (null != currentTagNames && currentTagNames.isEmpty()) {
tagCombo.addItem(NO_TAG_NAMES_MESSAGE);
}
else {
} else {
for (TagName tagName : currentTagNames) {
tagNames.put(tagName.getDisplayName(), tagName);
tagCombo.addItem(tagName.getDisplayName());
}
}
}
// Center and show the dialog box.
this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
setVisible(true);
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
@ -216,7 +216,7 @@ public class GetTagNameAndCommentDialog extends JDialog {
}// </editor-fold>//GEN-END:initComponents
private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
tagNameAndComment = new TagNameAndComment(tagNames.get((String)tagCombo.getSelectedItem()), commentText.getText());
tagNameAndComment = new TagNameAndComment(tagNames.get((String) tagCombo.getSelectedItem()), commentText.getText());
dispose();
}//GEN-LAST:event_okButtonActionPerformed

View File

@ -43,6 +43,7 @@ import org.sleuthkit.datamodel.TagName;
import org.sleuthkit.datamodel.TskCoreException;
public class GetTagNameDialog extends JDialog {
private static final String TAG_ICON_PATH = "org/sleuthkit/autopsy/images/tag-folder-blue-icon-16.png"; //NON-NLS
private final HashMap<String, TagName> tagNames = new HashMap<>();
private TagName tagName = null;
@ -50,15 +51,15 @@ public class GetTagNameDialog extends JDialog {
public static TagName doDialog() {
GetTagNameDialog dialog = new GetTagNameDialog();
return dialog.tagName;
}
}
private GetTagNameDialog() {
super((JFrame)WindowManager.getDefault().getMainWindow(),
NbBundle.getMessage(GetTagNameDialog.class, "GetTagNameDialog.createTag"),
true);
super((JFrame) WindowManager.getDefault().getMainWindow(),
NbBundle.getMessage(GetTagNameDialog.class, "GetTagNameDialog.createTag"),
true);
setIconImage(ImageUtilities.loadImage(TAG_ICON_PATH));
initComponents();
// Set up the dialog to close when Esc is pressed.
String cancelName = NbBundle.getMessage(this.getClass(), "GetTagNameDialog.cancelName");
InputMap inputMap = getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
@ -70,52 +71,51 @@ public class GetTagNameDialog extends JDialog {
dispose();
}
});
// Get the current set of tag names and hash them for a speedy lookup in
// case the user chooses an existing tag name from the tag names table.
TagsManager tagsManager = Case.getCurrentCase().getServices().getTagsManager();
List<TagName> currentTagNames = null;
try {
currentTagNames = tagsManager.getAllTagNames();
}
catch (TskCoreException ex) {
currentTagNames = tagsManager.getAllTagNames();
} catch (TskCoreException ex) {
Logger.getLogger(GetTagNameDialog.class.getName()).log(Level.SEVERE, "Failed to get tag names", ex); //NON-NLS
}
}
if (null != currentTagNames) {
for (TagName name : currentTagNames) {
this.tagNames.put(name.getDisplayName(), name);
}
}
else {
}
} else {
currentTagNames = new ArrayList<>();
}
// Populate the tag names table.
tagsTable.setModel(new TagsTableModel(currentTagNames));
tagsTable.setTableHeader(null);
tagsTable.setCellSelectionEnabled(false);
tagsTable.setFocusable(false);
tagsTable.setRowHeight(tagsTable.getRowHeight() + 5);
// Center and show the dialog box.
this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
setVisible(true);
}
private boolean containsIllegalCharacters(String content) {
return (content.contains("\\")||
content.contains(":") ||
content.contains("*") ||
content.contains("?") ||
content.contains("\"")||
content.contains("<") ||
content.contains(">") ||
content.contains("|"));
return (content.contains("\\")
|| content.contains(":")
|| content.contains("*")
|| content.contains("?")
|| content.contains("\"")
|| content.contains("<")
|| content.contains(">")
|| content.contains("|"));
}
private class TagsTableModel extends AbstractTableModel {
private class TagsTableModel extends AbstractTableModel {
private final ArrayList<TagName> tagNames = new ArrayList<>();
TagsTableModel(List<TagName> tagNames) {
for (TagName tagName : tagNames) {
this.tagNames.add(tagName);
@ -142,7 +142,7 @@ public class GetTagNameDialog extends JDialog {
return tagNames.get(rowIndex).getDisplayName();
}
}
/**
* 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
@ -280,46 +280,41 @@ public class GetTagNameDialog extends JDialog {
String tagDisplayName = tagNameField.getText();
if (tagDisplayName.isEmpty()) {
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(this.getClass(),
"GetTagNameDialog.mustSupplyTtagName.msg"),
NbBundle.getMessage(this.getClass(), "GetTagNameDialog.tagNameErr"),
JOptionPane.ERROR_MESSAGE);
}
else if (containsIllegalCharacters(tagDisplayName)) {
NbBundle.getMessage(this.getClass(),
"GetTagNameDialog.mustSupplyTtagName.msg"),
NbBundle.getMessage(this.getClass(), "GetTagNameDialog.tagNameErr"),
JOptionPane.ERROR_MESSAGE);
} else if (containsIllegalCharacters(tagDisplayName)) {
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(this.getClass(), "GetTagNameDialog.illegalChars.msg"),
NbBundle.getMessage(this.getClass(), "GetTagNameDialog.illegalCharsErr"),
JOptionPane.ERROR_MESSAGE);
}
else {
NbBundle.getMessage(this.getClass(), "GetTagNameDialog.illegalChars.msg"),
NbBundle.getMessage(this.getClass(), "GetTagNameDialog.illegalCharsErr"),
JOptionPane.ERROR_MESSAGE);
} else {
tagName = tagNames.get(tagDisplayName);
if (tagName == null) {
try {
tagName = Case.getCurrentCase().getServices().getTagsManager().addTagName(tagDisplayName);
dispose();
}
catch (TskCoreException ex) {
} catch (TskCoreException ex) {
Logger.getLogger(AddTagAction.class.getName()).log(Level.SEVERE, "Error adding " + tagDisplayName + " tag name", ex); //NON-NLS
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(this.getClass(),
"GetTagNameDialog.unableToAddTagNameToCase.msg",
tagDisplayName),
NbBundle.getMessage(this.getClass(), "GetTagNameDialog.taggingErr"),
JOptionPane.ERROR_MESSAGE);
NbBundle.getMessage(this.getClass(),
"GetTagNameDialog.unableToAddTagNameToCase.msg",
tagDisplayName),
NbBundle.getMessage(this.getClass(), "GetTagNameDialog.taggingErr"),
JOptionPane.ERROR_MESSAGE);
tagName = null;
}
catch (TagsManager.TagNameAlreadyExistsException ex) {
} catch (TagsManager.TagNameAlreadyExistsException ex) {
Logger.getLogger(AddTagAction.class.getName()).log(Level.SEVERE, "Error adding " + tagDisplayName + " tag name", ex); //NON-NLS
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(this.getClass(),
"GetTagNameDialog.tagNameAlreadyDef.msg",
tagDisplayName),
NbBundle.getMessage(this.getClass(), "GetTagNameDialog.dupTagErr"),
JOptionPane.ERROR_MESSAGE);
NbBundle.getMessage(this.getClass(),
"GetTagNameDialog.tagNameAlreadyDef.msg",
tagDisplayName),
NbBundle.getMessage(this.getClass(), "GetTagNameDialog.dupTagErr"),
JOptionPane.ERROR_MESSAGE);
tagName = null;
}
}
else {
} else {
dispose();
}
}
@ -349,4 +344,3 @@ public class GetTagNameDialog extends JDialog {
// End of variables declaration//GEN-END:variables
}

View File

@ -33,7 +33,6 @@ import org.openide.util.Exceptions;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case;
/**
* Action in menu to open the folder containing the log files
*/
@ -49,13 +48,12 @@ public final class OpenLogFolderAction implements ActionListener {
File logDir;
if (Case.isCaseOpen()) {
logDir = new File(Case.getCurrentCase().getLogDirectoryPath());
}
else {
} else {
logDir = new File(Places.getUserDirectory().getAbsolutePath() + File.separator + "var" + File.separator + "log");
}
if (logDir.exists() == false) {
NotifyDescriptor d =
new NotifyDescriptor.Message(
NotifyDescriptor d
= new NotifyDescriptor.Message(
NbBundle.getMessage(this.getClass(), "OpenLogFolder.error1", logDir.getAbsolutePath()),
NotifyDescriptor.ERROR_MESSAGE);
DialogDisplayer.getDefault().notify(d);

View File

@ -35,7 +35,7 @@ import org.sleuthkit.autopsy.ingest.IngestProgressSnapshotDialog;
)
@ActionRegistration(
displayName = "#CTL_ShowIngestProgressSnapshotAction",
lazy=false
lazy = false
)
@ActionReference(path = "Menu/Help", position = 1125)
@Messages("CTL_ShowIngestProgressSnapshotAction=Ingest Status Details")

View File

@ -16,7 +16,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
import java.awt.Component;
@ -44,8 +43,9 @@ import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.datamodel.Image;
/**
* The action to add an image to the current Case. This action should be disabled
* on creation and it will be enabled on new case creation or case opened.
* The action to add an image to the current Case. This action should be
* disabled on creation and it will be enabled on new case creation or case
* opened.
*
* @author jantonius
*/
@ -73,7 +73,6 @@ public final class AddImageAction extends CallableSystemAction implements Presen
// boolean: whether or not to skip processing orphan files on FAT filesystems
static final String NOFATORPHANS_PROP = "nofatorphans"; //NON-NLS
static final Logger logger = Logger.getLogger(AddImageAction.class.getName());
private WizardDescriptor wizardDescriptor;
@ -101,7 +100,7 @@ public final class AddImageAction extends CallableSystemAction implements Presen
/**
* Pop-up the "Add Image" wizard panel.
*
*
* @param e
*/
@Override
@ -109,9 +108,9 @@ public final class AddImageAction extends CallableSystemAction implements Presen
if (IngestManager.getInstance().isIngestRunning()) {
final String msg = NbBundle.getMessage(this.getClass(), "AddImageAction.ingestConfig.ongoingIngest.msg");
if (JOptionPane.showConfirmDialog(null, msg,
NbBundle.getMessage(this.getClass(),
"AddImageAction.ingestConfig.ongoingIngest.title"),
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.NO_OPTION) {
NbBundle.getMessage(this.getClass(),
"AddImageAction.ingestConfig.ongoingIngest.title"),
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.NO_OPTION) {
return;
}
}
@ -127,12 +126,12 @@ public final class AddImageAction extends CallableSystemAction implements Presen
dialog = DialogDisplayer.getDefault().createDialog(wizardDescriptor);
dialog.setVisible(true);
dialog.toFront();
// Do any cleanup that needs to happen (potentially: stopping the
//add-image process, reverting an image)
runCleanupTasks();
}
}
/**
* Closes the current dialog and wizard, and opens a new one. Used in the
* "Add another image" action on the last panel
@ -144,22 +143,24 @@ public final class AddImageAction extends CallableSystemAction implements Presen
// let the previous call to AddImageAction.actionPerformed() finish up
// after the wizard, this will run when its it's done
final Runnable r = new Runnable() {
final Runnable r = new Runnable() {
@Override
public void run() {
actionPerformed(null);
}
};
SwingUtilities.invokeLater(r);
}
public interface IndexImageTask {
void runTask(Image newImage);
}
/**
* This method does nothing. Use the "actionPerformed(ActionEvent e)" instead of this method.
* This method does nothing. Use the "actionPerformed(ActionEvent e)"
* instead of this method.
*/
@Override
public void performAction() {
@ -187,8 +188,8 @@ public final class AddImageAction extends CallableSystemAction implements Presen
/**
* Returns the toolbar component of this action
*
* @return component the toolbar button
*
* @return component the toolbar button
*/
@Override
public Component getToolbarPresenter() {
@ -201,7 +202,7 @@ public final class AddImageAction extends CallableSystemAction implements Presen
/**
* Set this action to be enabled/disabled
*
* @param value whether to enable this action or not
* @param value whether to enable this action or not
*/
@Override
public void setEnabled(boolean value) {
@ -216,7 +217,7 @@ public final class AddImageAction extends CallableSystemAction implements Presen
* "Cancel", and "Finish". If you change the name of any of those buttons,
* use the latest name instead.
*
* @param buttonText the text of the button
* @param buttonText the text of the button
*/
public void requestFocusButton(String buttonText) {
// get all buttons on this wizard panel
@ -229,7 +230,7 @@ public final class AddImageAction extends CallableSystemAction implements Presen
}
}
}
/**
* Run and clear any cleanup tasks for wizard closing that might be
* registered. This should be run even when the wizard exits cleanly, so
@ -238,16 +239,16 @@ public final class AddImageAction extends CallableSystemAction implements Presen
private void runCleanupTasks() {
cleanupSupport.fireChange();
}
ChangeSupport cleanupSupport = new ChangeSupport(this);
/**
* Instances of this class implement the cleanup() method to run cleanup
* code when the wizard exits.
*
*
* After enable() has been called on an instance it will run once after the
* wizard closes (on both a cancel and a normal finish).
*
*
* If disable() is called before the wizard exits, the task will not run.
*/
abstract class CleanupTask implements ChangeListener {
@ -274,7 +275,8 @@ public final class AddImageAction extends CallableSystemAction implements Presen
/**
* Performs cleanup action when called
* @throws Exception
*
* @throws Exception
*/
abstract void cleanup() throws Exception;

View File

@ -21,7 +21,7 @@ package org.sleuthkit.autopsy.casemodule;
/**
* Dialog to show add image error messages
*/
public class AddImageErrorsDialog extends javax.swing.JDialog {
public class AddImageErrorsDialog extends javax.swing.JDialog {
/**
* Creates new form AddImageErrorsDialog

View File

@ -16,10 +16,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -39,282 +37,278 @@ import org.sleuthkit.datamodel.TskDataException;
import org.sleuthkit.datamodel.TskException;
/*
* A background task that adds the given image to
* database using the Sleuthkit JNI interface.
*
* A background task that adds the given image to database using the Sleuthkit
* JNI interface.
*
* It updates the given ProgressMonitor as it works through adding the image,
* and et the end, calls the specified Callback.
*/
class AddImageTask implements Runnable {
class AddImageTask implements Runnable {
private final Logger logger = Logger.getLogger(AddImageTask.class.getName());
private final Case currentCase;
// true if the process was requested to cancel
private final Object lock = new Object(); // synchronization object for cancelRequested
private volatile boolean cancelRequested = false;
//true if revert has been invoked.
private boolean reverted = false;
// true if there was a critical error in adding the data source
private boolean hasCritError = false;
private final List<String> errorList = new ArrayList<>();
private final DataSourceProcessorProgressMonitor progressMonitor;
private final DataSourceProcessorCallback callbackObj;
private final List<Content> newContents = Collections.synchronizedList(new ArrayList<Content>());
private SleuthkitJNI.CaseDbHandle.AddImageProcess addImageProcess;
private Thread dirFetcher;
private final String imagePath;
String timeZone;
boolean noFatOrphans;
/*
* A thread that updates the progressMonitor with the name of the
* directory currently being processed by the AddImageTask
*/
private class CurrentDirectoryFetcher implements Runnable {
private final Logger logger = Logger.getLogger(AddImageTask.class.getName());
DataSourceProcessorProgressMonitor progressMonitor;
SleuthkitJNI.CaseDbHandle.AddImageProcess process;
private final Case currentCase;
CurrentDirectoryFetcher(DataSourceProcessorProgressMonitor aProgressMonitor, SleuthkitJNI.CaseDbHandle.AddImageProcess proc) {
this.progressMonitor = aProgressMonitor;
this.process = proc;
}
// true if the process was requested to cancel
private final Object lock = new Object(); // synchronization object for cancelRequested
private volatile boolean cancelRequested = false;
/**
* @return the currently processing directory
*/
@Override
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
String currDir = process.currentDirectory();
if (currDir != null) {
if (!currDir.isEmpty() ) {
progressMonitor.setProgressText(
NbBundle.getMessage(this.getClass(), "AddImageTask.run.progress.adding",
currDir));
}
}
// this sleep here prevents the UI from locking up
// due to too frequent updates to the progressMonitor above
Thread.sleep(500);
}
} catch (InterruptedException ie) {
// nothing to do, thread was interrupted externally
// signaling the end of AddImageProcess
}
}
}
public AddImageTask(String imgPath, String tz, boolean noOrphans, DataSourceProcessorProgressMonitor aProgressMonitor, DataSourceProcessorCallback cbObj ) {
currentCase = Case.getCurrentCase();
this.imagePath = imgPath;
this.timeZone = tz;
this.noFatOrphans = noOrphans;
this.callbackObj = cbObj;
//true if revert has been invoked.
private boolean reverted = false;
// true if there was a critical error in adding the data source
private boolean hasCritError = false;
private final List<String> errorList = new ArrayList<>();
private final DataSourceProcessorProgressMonitor progressMonitor;
private final DataSourceProcessorCallback callbackObj;
private final List<Content> newContents = Collections.synchronizedList(new ArrayList<Content>());
private SleuthkitJNI.CaseDbHandle.AddImageProcess addImageProcess;
private Thread dirFetcher;
private final String imagePath;
String timeZone;
boolean noFatOrphans;
/*
* A thread that updates the progressMonitor with the name of the directory
* currently being processed by the AddImageTask
*/
private class CurrentDirectoryFetcher implements Runnable {
DataSourceProcessorProgressMonitor progressMonitor;
SleuthkitJNI.CaseDbHandle.AddImageProcess process;
CurrentDirectoryFetcher(DataSourceProcessorProgressMonitor aProgressMonitor, SleuthkitJNI.CaseDbHandle.AddImageProcess proc) {
this.progressMonitor = aProgressMonitor;
this.process = proc;
}
/**
* Starts the addImage process, but does not commit the results.
*
* @return
*
* @throws Exception
* @return the currently processing directory
*/
@Override
public void run() {
errorList.clear();
public void run() {
try {
currentCase.getSleuthkitCase().acquireExclusiveLock();
addImageProcess = currentCase.makeAddImageProcess(timeZone, true, noFatOrphans);
dirFetcher = new Thread( new CurrentDirectoryFetcher(progressMonitor, addImageProcess));
try {
progressMonitor.setIndeterminate(true);
progressMonitor.setProgress(0);
dirFetcher.start();
addImageProcess.run(new String[]{this.imagePath});
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Core errors occurred while running add image. ", ex); //NON-NLS
hasCritError = true;
errorList.add(ex.getMessage());
} catch (TskDataException ex) {
logger.log(Level.WARNING, "Data errors occurred while running add image. ", ex); //NON-NLS
errorList.add(ex.getMessage());
}
postProcess();
} finally {
currentCase.getSleuthkitCase().releaseExclusiveLock();
}
}
/**
* Commit the newly added image to DB
*
*
* @throws Exception if commit or adding the image to the case failed
*/
private void commitImage() throws Exception {
long imageId = 0;
try {
imageId = addImageProcess.commit();
} catch (TskCoreException e) {
logger.log(Level.WARNING, "Errors occured while committing the image", e); //NON-NLS
errorList.add(e.getMessage());
} finally {
if (imageId != 0) {
// get the newly added Image so we can return to caller
Image newImage = currentCase.getSleuthkitCase().getImageById(imageId);
//while we have the image, verify the size of its contents
String verificationErrors = newImage.verifyImageSize();
if (verificationErrors.equals("") == false) {
//data error (non-critical)
errorList.add(verificationErrors);
}
// Add the image to the list of new content
newContents.add(newImage);
}
logger.log(Level.INFO, "Image committed, imageId: {0}", imageId); //NON-NLS
logger.log(Level.INFO, PlatformUtil.getAllMemUsageInfo());
}
}
/**
* Post processing after the addImageProcess is done.
*
*/
private void postProcess() {
// cancel the directory fetcher
dirFetcher.interrupt();
if (cancelRequested() || hasCritError) {
logger.log(Level.WARNING, "Critical errors or interruption in add image process. Image will not be committed."); //NON-NLS
revert();
}
if (!errorList.isEmpty()) {
logger.log(Level.INFO, "There were errors that occured in add image process"); //NON-NLS
}
// When everything happens without an error:
if (!(cancelRequested() || hasCritError)) {
try {
if (addImageProcess != null) {
// commit image
try {
commitImage();
} catch (Exception ex) {
errorList.add(ex.getMessage());
// Log error/display warning
logger.log(Level.SEVERE, "Error adding image to case.", ex); //NON-NLS
while (!Thread.currentThread().isInterrupted()) {
String currDir = process.currentDirectory();
if (currDir != null) {
if (!currDir.isEmpty()) {
progressMonitor.setProgressText(
NbBundle.getMessage(this.getClass(), "AddImageTask.run.progress.adding",
currDir));
}
} else {
logger.log(Level.SEVERE, "Missing image process object"); //NON-NLS
}
// Tell the progress monitor we're done
progressMonitor.setProgress(100);
} catch (Exception ex) {
//handle unchecked exceptions post image add
errorList.add(ex.getMessage());
logger.log(Level.WARNING, "Unexpected errors occurred while running post add image cleanup. ", ex); //NON-NLS
logger.log(Level.SEVERE, "Error adding image to case", ex); //NON-NLS
}
}
// invoke the callBack, unless the caller cancelled
if (!cancelRequested()) {
doCallBack();
}
}
/*
* Call the callback with results, new content, and errors, if any
*/
private void doCallBack()
{
DataSourceProcessorCallback.DataSourceProcessorResult result;
if (hasCritError) {
result = DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS;
}
else if (!errorList.isEmpty()) {
result = DataSourceProcessorCallback.DataSourceProcessorResult.NONCRITICAL_ERRORS;
}
else {
result = DataSourceProcessorCallback.DataSourceProcessorResult.NO_ERRORS;
}
// invoke the callback, passing it the result, list of new contents, and list of errors
callbackObj.done(result, errorList, newContents);
}
/*
* cancel the image addition, if possible
*/
public void cancelTask() {
synchronized (lock) {
cancelRequested = true;
try {
interrupt();
// this sleep here prevents the UI from locking up
// due to too frequent updates to the progressMonitor above
Thread.sleep(500);
}
catch (Exception ex) {
logger.log(Level.SEVERE, "Failed to interrupt the add image task..."); //NON-NLS
}
}
}
/*
* Interrupt the add image process if it is still running
*/
private void interrupt() throws Exception {
try {
logger.log(Level.INFO, "interrupt() add image process"); //NON-NLS
addImageProcess.stop(); //it might take time to truly stop processing and writing to db
} catch (TskCoreException ex) {
throw new Exception(NbBundle.getMessage(this.getClass(), "AddImageTask.interrupt.exception.msg"), ex);
}
}
/*
* Revert - if image has already been added but not committed yet
*/
private void revert() {
if (!reverted) {
logger.log(Level.INFO, "Revert after add image process"); //NON-NLS
try {
addImageProcess.revert();
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Error reverting add image process", ex); //NON-NLS
}
reverted = true;
}
}
private boolean cancelRequested() {
synchronized (lock) {
return cancelRequested;
} catch (InterruptedException ie) {
// nothing to do, thread was interrupted externally
// signaling the end of AddImageProcess
}
}
}
public AddImageTask(String imgPath, String tz, boolean noOrphans, DataSourceProcessorProgressMonitor aProgressMonitor, DataSourceProcessorCallback cbObj) {
currentCase = Case.getCurrentCase();
this.imagePath = imgPath;
this.timeZone = tz;
this.noFatOrphans = noOrphans;
this.callbackObj = cbObj;
this.progressMonitor = aProgressMonitor;
}
/**
* Starts the addImage process, but does not commit the results.
*
* @return
*
* @throws Exception
*/
@Override
public void run() {
errorList.clear();
try {
currentCase.getSleuthkitCase().acquireExclusiveLock();
addImageProcess = currentCase.makeAddImageProcess(timeZone, true, noFatOrphans);
dirFetcher = new Thread(new CurrentDirectoryFetcher(progressMonitor, addImageProcess));
try {
progressMonitor.setIndeterminate(true);
progressMonitor.setProgress(0);
dirFetcher.start();
addImageProcess.run(new String[]{this.imagePath});
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Core errors occurred while running add image. ", ex); //NON-NLS
hasCritError = true;
errorList.add(ex.getMessage());
} catch (TskDataException ex) {
logger.log(Level.WARNING, "Data errors occurred while running add image. ", ex); //NON-NLS
errorList.add(ex.getMessage());
}
postProcess();
} finally {
currentCase.getSleuthkitCase().releaseExclusiveLock();
}
}
/**
* Commit the newly added image to DB
*
*
* @throws Exception if commit or adding the image to the case failed
*/
private void commitImage() throws Exception {
long imageId = 0;
try {
imageId = addImageProcess.commit();
} catch (TskCoreException e) {
logger.log(Level.WARNING, "Errors occured while committing the image", e); //NON-NLS
errorList.add(e.getMessage());
} finally {
if (imageId != 0) {
// get the newly added Image so we can return to caller
Image newImage = currentCase.getSleuthkitCase().getImageById(imageId);
//while we have the image, verify the size of its contents
String verificationErrors = newImage.verifyImageSize();
if (verificationErrors.equals("") == false) {
//data error (non-critical)
errorList.add(verificationErrors);
}
// Add the image to the list of new content
newContents.add(newImage);
}
logger.log(Level.INFO, "Image committed, imageId: {0}", imageId); //NON-NLS
logger.log(Level.INFO, PlatformUtil.getAllMemUsageInfo());
}
}
/**
* Post processing after the addImageProcess is done.
*
*/
private void postProcess() {
// cancel the directory fetcher
dirFetcher.interrupt();
if (cancelRequested() || hasCritError) {
logger.log(Level.WARNING, "Critical errors or interruption in add image process. Image will not be committed."); //NON-NLS
revert();
}
if (!errorList.isEmpty()) {
logger.log(Level.INFO, "There were errors that occured in add image process"); //NON-NLS
}
// When everything happens without an error:
if (!(cancelRequested() || hasCritError)) {
try {
if (addImageProcess != null) {
// commit image
try {
commitImage();
} catch (Exception ex) {
errorList.add(ex.getMessage());
// Log error/display warning
logger.log(Level.SEVERE, "Error adding image to case.", ex); //NON-NLS
}
} else {
logger.log(Level.SEVERE, "Missing image process object"); //NON-NLS
}
// Tell the progress monitor we're done
progressMonitor.setProgress(100);
} catch (Exception ex) {
//handle unchecked exceptions post image add
errorList.add(ex.getMessage());
logger.log(Level.WARNING, "Unexpected errors occurred while running post add image cleanup. ", ex); //NON-NLS
logger.log(Level.SEVERE, "Error adding image to case", ex); //NON-NLS
}
}
// invoke the callBack, unless the caller cancelled
if (!cancelRequested()) {
doCallBack();
}
}
/*
* Call the callback with results, new content, and errors, if any
*/
private void doCallBack() {
DataSourceProcessorCallback.DataSourceProcessorResult result;
if (hasCritError) {
result = DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS;
} else if (!errorList.isEmpty()) {
result = DataSourceProcessorCallback.DataSourceProcessorResult.NONCRITICAL_ERRORS;
} else {
result = DataSourceProcessorCallback.DataSourceProcessorResult.NO_ERRORS;
}
// invoke the callback, passing it the result, list of new contents, and list of errors
callbackObj.done(result, errorList, newContents);
}
/*
* cancel the image addition, if possible
*/
public void cancelTask() {
synchronized (lock) {
cancelRequested = true;
try {
interrupt();
} catch (Exception ex) {
logger.log(Level.SEVERE, "Failed to interrupt the add image task..."); //NON-NLS
}
}
}
/*
* Interrupt the add image process if it is still running
*/
private void interrupt() throws Exception {
try {
logger.log(Level.INFO, "interrupt() add image process"); //NON-NLS
addImageProcess.stop(); //it might take time to truly stop processing and writing to db
} catch (TskCoreException ex) {
throw new Exception(NbBundle.getMessage(this.getClass(), "AddImageTask.interrupt.exception.msg"), ex);
}
}
/*
* Revert - if image has already been added but not committed yet
*/
private void revert() {
if (!reverted) {
logger.log(Level.INFO, "Revert after add image process"); //NON-NLS
try {
addImageProcess.revert();
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Error reverting add image process", ex); //NON-NLS
}
reverted = true;
}
}
private boolean cancelRequested() {
synchronized (lock) {
return cancelRequested;
}
}
}

View File

@ -18,7 +18,6 @@
*/
package org.sleuthkit.autopsy.casemodule;
import java.awt.Color;
import java.awt.EventQueue;
import java.util.HashSet;
@ -55,48 +54,48 @@ class AddImageWizardAddingProgressPanel implements WizardDescriptor.FinishablePa
private final Set<ChangeListener> listeners = new HashSet<>(1); // or can use ChangeSupport in NB 6.0
private DSPProgressMonitorImpl dspProgressMonitorImpl = new DSPProgressMonitorImpl();
public DSPProgressMonitorImpl getDSPProgressMonitorImpl() {
return dspProgressMonitorImpl;
}
private class DSPProgressMonitorImpl implements DataSourceProcessorProgressMonitor {
@Override
public void setIndeterminate(final boolean indeterminate) {
// update the progress bar asynchronously
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
getComponent().getProgressBar().setIndeterminate(indeterminate);
}
});
// update the progress bar asynchronously
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
getComponent().getProgressBar().setIndeterminate(indeterminate);
}
});
}
@Override
public void setProgress(final int progress) {
// update the progress bar asynchronously
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
getComponent().getProgressBar().setValue(progress);
}
});
public void setProgress(final int progress) {
// update the progress bar asynchronously
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
getComponent().getProgressBar().setValue(progress);
}
});
}
@Override
public void setProgressText(final String text) {
// update the progress UI asynchronously
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
getComponent().setProgressMsgText(text);
}
});
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
getComponent().setProgressMsgText(text);
}
});
}
}
/**
* Get the visual component for the panel. In this template, the component
* is kept separate. This can be more efficient: if the wizard is created

View File

@ -29,7 +29,7 @@ import org.openide.util.NbBundle;
* visual component to display progress bar and status updates while adding an
* image in the wizard
*/
class AddImageWizardAddingProgressVisual extends javax.swing.JPanel {
class AddImageWizardAddingProgressVisual extends javax.swing.JPanel {
private static final String ADDING_DATA_SOURCE_COMPLETE = NbBundle
.getMessage(AddImageWizardAddingProgressVisual.class, "AddImageWizardAddingProgressVisual.addingDsComplete.text");

View File

@ -53,12 +53,12 @@ class AddImageWizardChooseDataSourcePanel implements WizardDescriptor.Panel<Wiza
// paths to any set hash lookup databases (can be null)
private String NSRLPath, knownBadPath;
AddImageWizardChooseDataSourcePanel(AddImageWizardAddingProgressPanel proPanel) {
AddImageWizardChooseDataSourcePanel(AddImageWizardAddingProgressPanel proPanel) {
this.progressPanel = proPanel;
}
/**
* Get the visual component for the panel. In this template, the component
* is kept separate. This can be more efficient: if the wizard is created
@ -95,7 +95,7 @@ class AddImageWizardChooseDataSourcePanel implements WizardDescriptor.Panel<Wiza
* one. If the panel is valid, the "Next" button will be enabled.
*
* @return boolean true if all the fields are correctly filled, false
* otherwise
* otherwise
*/
@Override
public boolean isValid() {
@ -180,7 +180,6 @@ class AddImageWizardChooseDataSourcePanel implements WizardDescriptor.Panel<Wiza
//reset settings if supports it
//getComponent().reset();
// Prepopulate the image directory from the properties file
try {
@ -219,7 +218,7 @@ class AddImageWizardChooseDataSourcePanel implements WizardDescriptor.Panel<Wiza
*/
@Override
public void storeSettings(WizardDescriptor settings) {
return;
}

View File

@ -38,6 +38,7 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
import org.sleuthkit.autopsy.ingest.IngestJobSettings;
import org.sleuthkit.autopsy.ingest.IngestJobSettingsPanel;
import org.sleuthkit.autopsy.ingest.IngestManager;
/**
* second panel of add image wizard, allows user to configure ingest modules.
*
@ -46,36 +47,34 @@ import org.sleuthkit.autopsy.ingest.IngestManager;
*/
class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDescriptor> {
private IngestJobSettingsPanel ingestJobSettingsPanel;
/**
* The visual component that displays this panel. If you need to access the
* component from this class, just use getComponent().
*/
private Component component = null;
private final List<Content> newContents = Collections.synchronizedList(new ArrayList<Content>());
private boolean ingested = false;
private boolean readyToIngest = false;
// task that will clean up the created database file if the wizard is cancelled before it finishes
private AddImageAction.CleanupTask cleanupTask;
private AddImageAction.CleanupTask cleanupTask;
private final AddImageAction addImageAction;
private final AddImageWizardAddingProgressPanel progressPanel;
private final AddImageWizardChooseDataSourcePanel dataSourcePanel;
private DataSourceProcessor dsProcessor;
AddImageWizardIngestConfigPanel(AddImageWizardChooseDataSourcePanel dsPanel, AddImageAction action, AddImageWizardAddingProgressPanel proPanel) {
this.addImageAction = action;
this.progressPanel = proPanel;
this.dataSourcePanel = dsPanel;
IngestJobSettings ingestJobSettings = new IngestJobSettings(AddImageWizardIngestConfigPanel.class.getCanonicalName());
IngestJobSettings ingestJobSettings = new IngestJobSettings(AddImageWizardIngestConfigPanel.class.getCanonicalName());
showWarnings(ingestJobSettings);
this.ingestJobSettingsPanel = new IngestJobSettingsPanel(ingestJobSettings);
}
@ -167,7 +166,7 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
readyToIngest = false;
newContents.clear();
// Start processing the data source by handing it off to the selected DSP,
// so it gets going in the background while the user is still picking the Ingest modules
startDataSourceProcessing(settings);
@ -187,7 +186,7 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
IngestJobSettings ingestJobSettings = this.ingestJobSettingsPanel.getSettings();
ingestJobSettings.save();
showWarnings(ingestJobSettings);
// Start ingest if it hasn't already been started
readyToIngest = true;
startIngest();
@ -203,7 +202,7 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
JOptionPane.showMessageDialog(null, warningMessage.toString());
}
}
/**
* Start ingest after verifying we have a new image, we are ready to ingest,
* and we haven't already ingested.
@ -215,14 +214,13 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
progressPanel.setStateFinished();
}
}
/**
* Starts the Data source processing by kicking off the selected DataSourceProcessor
/**
* Starts the Data source processing by kicking off the selected
* DataSourceProcessor
*/
private void startDataSourceProcessing(WizardDescriptor settings) {
// Add a cleanup task to interrupt the background process if the
// wizard exits while the background process is running.
cleanupTask = addImageAction.new CleanupTask() {
@ -231,43 +229,43 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
cancelDataSourceProcessing();
}
};
cleanupTask.enable();
// get the selected DSProcessor
dsProcessor = dataSourcePanel.getComponent().getCurrentDSProcessor();
DataSourceProcessorCallback cbObj = new DataSourceProcessorCallback () {
// get the selected DSProcessor
dsProcessor = dataSourcePanel.getComponent().getCurrentDSProcessor();
DataSourceProcessorCallback cbObj = new DataSourceProcessorCallback() {
@Override
public void doneEDT(DataSourceProcessorCallback.DataSourceProcessorResult result, List<String> errList, List<Content> contents) {
dataSourceProcessorDone(result, errList, contents );
public void doneEDT(DataSourceProcessorCallback.DataSourceProcessorResult result, List<String> errList, List<Content> contents) {
dataSourceProcessorDone(result, errList, contents);
}
};
progressPanel.setStateStarted();
// Kick off the DSProcessor
dsProcessor.run(progressPanel.getDSPProgressMonitorImpl(), cbObj);
}
/*
* Cancels the data source processing - in case the users presses 'Cancel'
*/
private void cancelDataSourceProcessing() {
dsProcessor.cancel();
dsProcessor.cancel();
}
/*
* Callback for the data source processor.
* Invoked by the DSP on the EDT thread, when it finishes processing the data source.
* Callback for the data source processor. Invoked by the DSP on the EDT
* thread, when it finishes processing the data source.
*/
private void dataSourceProcessorDone(DataSourceProcessorCallback.DataSourceProcessorResult result, List<String> errList, List<Content> contents) {
// disable the cleanup task
private void dataSourceProcessorDone(DataSourceProcessorCallback.DataSourceProcessorResult result, List<String> errList, List<Content> contents) {
// disable the cleanup task
cleanupTask.disable();
// Get attention for the process finish
java.awt.Toolkit.getDefaultToolkit().beep(); //BEEP!
AddImageWizardAddingProgressVisual panel = progressPanel.getComponent();
@ -279,40 +277,38 @@ class AddImageWizardIngestConfigPanel implements WizardDescriptor.Panel<WizardDe
}
// Tell the panel we're done
progressPanel.setStateFinished();
//check the result and display to user
if (result == DataSourceProcessorCallback.DataSourceProcessorResult.NO_ERRORS)
if (result == DataSourceProcessorCallback.DataSourceProcessorResult.NO_ERRORS) {
progressPanel.getComponent().setProgressBarTextAndColor(
NbBundle.getMessage(this.getClass(), "AddImageWizardIngestConfigPanel.dsProcDone.noErrs.text"), 100, Color.black);
else
} else {
progressPanel.getComponent().setProgressBarTextAndColor(
NbBundle.getMessage(this.getClass(), "AddImageWizardIngestConfigPanel.dsProcDone.errs.text"), 100, Color.red);
}
//if errors, display them on the progress panel
boolean critErr = false;
if (result == DataSourceProcessorCallback.DataSourceProcessorResult.CRITICAL_ERRORS) {
critErr = true;
}
for ( String err: errList ) {
for (String err : errList) {
// TBD: there probably should be an error level for each error
progressPanel.addErrors(err, critErr);
}
newContents.clear();
newContents.addAll(contents);
//notify the UI of the new content added to the case
if (!newContents.isEmpty()) {
Case.getCurrentCase().notifyNewDataSource(newContents.get(0));
Case.getCurrentCase().notifyNewDataSource(newContents.get(0));
}
// Start ingest if we can
// Start ingest if we can
progressPanel.setStateStarted();
startIngest();
}
}

View File

@ -16,7 +16,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
import java.awt.Component;
@ -43,18 +42,18 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDescript
}
/**
* Initialize panels representing individual wizard's steps and sets
* various properties for them influencing wizard appearance.
* Initialize panels representing individual wizard's steps and sets various
* properties for them influencing wizard appearance.
*/
private List<WizardDescriptor.Panel<WizardDescriptor>> getPanels() {
if (panels == null) {
panels = new ArrayList<WizardDescriptor.Panel<WizardDescriptor>>();
AddImageWizardAddingProgressPanel progressPanel = new AddImageWizardAddingProgressPanel();
AddImageWizardChooseDataSourcePanel dsPanel = new AddImageWizardChooseDataSourcePanel(progressPanel);
AddImageWizardIngestConfigPanel ingestConfigPanel = new AddImageWizardIngestConfigPanel(dsPanel, action, progressPanel);
panels.add(dsPanel);
panels.add(ingestConfigPanel);
panels.add(progressPanel);
@ -83,10 +82,10 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDescript
}
/**
* Returns the index of the current panel.
* Note: 0 = panel 1, 1 = panel 2, etc
* Returns the index of the current panel. Note: 0 = panel 1, 1 = panel 2,
* etc
*
* @return index the current panel index
* @return index the current panel index
*/
public int getIndex() {
return index;
@ -95,7 +94,7 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDescript
/**
* Gets the current panel.
*
* @return panel the current panel
* @return panel the current panel
*/
@Override
public WizardDescriptor.Panel<WizardDescriptor> current() {
@ -109,18 +108,18 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDescript
/**
* Gets the name of the current panel.
*
* @return name the name of the current panel
* @return name the name of the current panel
*/
@Override
public String name() {
return NbBundle.getMessage(this.getClass(), "AddImageWizardIterator.stepXofN", Integer.toString(index + 1),
getPanels().size());
getPanels().size());
}
/**
* Tests whether there is a next panel.
*
* @return boolean true if it has next panel, false if not
*
* @return boolean true if it has next panel, false if not
*/
@Override
public boolean hasNext() {
@ -130,7 +129,7 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDescript
/**
* Tests whether there is a previous panel.
*
* @return boolean true if it has previous panel, false if not
* @return boolean true if it has previous panel, false if not
*/
@Override
// disable the previous button on all panels
@ -159,8 +158,9 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDescript
if (!hasPrevious()) {
throw new NoSuchElementException();
}
if(index == 2)
if (index == 2) {
index--;
}
index--;
}

View File

@ -16,7 +16,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
/**
@ -32,201 +31,188 @@ import javax.swing.border.*;
import javax.swing.table.*;
/**
* The ButtonColumn class provides a renderer and an editor that looks like a
* JButton. The renderer and editor will then be used for a specified column
* in the table. The TableModel will contain the String to be displayed on
* the button.
* The ButtonColumn class provides a renderer and an editor that looks like a
* JButton. The renderer and editor will then be used for a specified column in
* the table. The TableModel will contain the String to be displayed on the
* button.
*
* The button can be invoked by a mouse click or by pressing the space bar
* when the cell has focus. Optionally a mnemonic can be set to invoke the
* button. When the button is invoked the provided Action is invoked. The
* source of the Action will be the table. The action command will contain
* the model row number of the button that was clicked.
* The button can be invoked by a mouse click or by pressing the space bar when
* the cell has focus. Optionally a mnemonic can be set to invoke the button.
* When the button is invoked the provided Action is invoked. The source of the
* Action will be the table. The action command will contain the model row
* number of the button that was clicked.
*
*/
class ButtonColumn extends AbstractCellEditor
implements TableCellRenderer, TableCellEditor, ActionListener, MouseListener
{
private JTable table;
private Action action;
private int mnemonic;
private Border originalBorder;
private Border focusBorder;
implements TableCellRenderer, TableCellEditor, ActionListener, MouseListener {
private JButton renderButton;
private JButton editButton;
private String text;
private boolean isButtonColumnEditor;
String buttonName;
private JTable table;
private Action action;
private int mnemonic;
private Border originalBorder;
private Border focusBorder;
private JButton renderButton;
private JButton editButton;
private String text;
private boolean isButtonColumnEditor;
/**
* Create the ButtonColumn to be used as a renderer and editor. The
* renderer and editor will automatically be installed on the TableColumn
* of the specified column.
*
* @param table the table containing the button renderer/editor
* @param action the Action to be invoked when the button is invoked
* @param column the column to which the button renderer/editor is added
* @param buttonName text displayed on the button
*/
ButtonColumn(JTable table, Action action, int column, String buttonName)
{
String buttonName;
/**
* Create the ButtonColumn to be used as a renderer and editor. The renderer
* and editor will automatically be installed on the TableColumn of the
* specified column.
*
* @param table the table containing the button renderer/editor
* @param action the Action to be invoked when the button is invoked
* @param column the column to which the button renderer/editor is added
* @param buttonName text displayed on the button
*/
ButtonColumn(JTable table, Action action, int column, String buttonName) {
this.table = table;
this.action = action;
this.buttonName = buttonName;
this.action = action;
this.buttonName = buttonName;
renderButton = new JButton();
editButton = new JButton();
editButton.setFocusPainted( false );
editButton.addActionListener( this );
originalBorder = editButton.getBorder();
setFocusBorder( new LineBorder(Color.BLUE) );
renderButton = new JButton();
editButton = new JButton();
editButton.setFocusPainted(false);
editButton.addActionListener(this);
originalBorder = editButton.getBorder();
setFocusBorder(new LineBorder(Color.BLUE));
TableColumnModel columnModel = table.getColumnModel();
columnModel.getColumn(column).setCellRenderer( this );
columnModel.getColumn(column).setCellEditor( this );
table.addMouseListener( this );
TableColumnModel columnModel = table.getColumnModel();
columnModel.getColumn(column).setCellRenderer(this);
columnModel.getColumn(column).setCellEditor(this);
table.addMouseListener(this);
}
/**
* Get foreground color of the button when the cell has focus
*
* @return the foreground color
*/
public Border getFocusBorder() {
return focusBorder;
}
/**
* Get foreground color of the button when the cell has focus
*
* @return the foreground color
*/
public Border getFocusBorder()
{
return focusBorder;
}
/**
* The foreground color of the button when the cell has focus
*
* @param focusBorder the foreground color
*/
public void setFocusBorder(Border focusBorder) {
this.focusBorder = focusBorder;
editButton.setBorder(focusBorder);
}
/**
* The foreground color of the button when the cell has focus
*
* @param focusBorder the foreground color
*/
public void setFocusBorder(Border focusBorder)
{
this.focusBorder = focusBorder;
editButton.setBorder( focusBorder );
}
public int getMnemonic() {
return mnemonic;
}
public int getMnemonic()
{
return mnemonic;
}
/**
* The mnemonic to activate the button when the cell has focus
*
* @param mnemonic the mnemonic
*/
public void setMnemonic(int mnemonic) {
this.mnemonic = mnemonic;
renderButton.setMnemonic(mnemonic);
editButton.setMnemonic(mnemonic);
}
/**
* The mnemonic to activate the button when the cell has focus
*
* @param mnemonic the mnemonic
*/
public void setMnemonic(int mnemonic)
{
this.mnemonic = mnemonic;
renderButton.setMnemonic(mnemonic);
editButton.setMnemonic(mnemonic);
}
@Override
public Component getTableCellEditorComponent(
JTable table, Object value, boolean isSelected, int row, int column) {
text = (value == null) ? "" : value.toString();
editButton.setText(text);
return editButton;
}
@Override
public Component getTableCellEditorComponent(
JTable table, Object value, boolean isSelected, int row, int column)
{
text = (value == null) ? "" : value.toString();
editButton.setText( text );
return editButton;
}
@Override
public Object getCellEditorValue()
{
return text;
}
@Override
public Object getCellEditorValue() {
return text;
}
//
// Implement TableCellRenderer interface
//
@Override
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
{
if (isSelected)
{
renderButton.setForeground(table.getSelectionForeground());
renderButton.setBackground(table.getSelectionBackground());
}
else
{
renderButton.setForeground(table.getForeground());
renderButton.setBackground(UIManager.getColor("Button.background"));
}
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (isSelected) {
renderButton.setForeground(table.getSelectionForeground());
renderButton.setBackground(table.getSelectionBackground());
} else {
renderButton.setForeground(table.getForeground());
renderButton.setBackground(UIManager.getColor("Button.background"));
}
if (hasFocus)
{
renderButton.setBorder( focusBorder );
}
else
{
renderButton.setBorder( originalBorder );
}
if (hasFocus) {
renderButton.setBorder(focusBorder);
} else {
renderButton.setBorder(originalBorder);
}
//renderButton.setText( (value == null) ? "" : value.toString() );
renderButton.setText(buttonName);
return renderButton;
}
//renderButton.setText( (value == null) ? "" : value.toString() );
renderButton.setText(buttonName);
return renderButton;
}
//
// Implement ActionListener interface
//
/*
* The button has been pressed. Stop editing and invoke the custom Action
* The button has been pressed. Stop editing and invoke the custom Action
*/
@Override
public void actionPerformed(ActionEvent e)
{
int row = table.convertRowIndexToModel( table.getEditingRow() );
fireEditingStopped();
public void actionPerformed(ActionEvent e) {
int row = table.convertRowIndexToModel(table.getEditingRow());
fireEditingStopped();
// Invoke the Action
ActionEvent event = new ActionEvent(
table,
ActionEvent.ACTION_PERFORMED,
"" + row);
action.actionPerformed(event);
}
ActionEvent event = new ActionEvent(
table,
ActionEvent.ACTION_PERFORMED,
"" + row);
action.actionPerformed(event);
}
//
// Implement MouseListener interface
//
/*
* When the mouse is pressed the editor is invoked. If you then then drag
* the mouse to another cell before releasing it, the editor is still
* active. Make sure editing is stopped when the mouse is released.
* When the mouse is pressed the editor is invoked. If you then then drag
* the mouse to another cell before releasing it, the editor is still
* active. Make sure editing is stopped when the mouse is released.
*/
@Override
public void mousePressed(MouseEvent e)
{
if (table.isEditing()
&& table.getCellEditor() == this)
isButtonColumnEditor = true;
public void mousePressed(MouseEvent e) {
if (table.isEditing()
&& table.getCellEditor() == this) {
isButtonColumnEditor = true;
}
}
@Override
public void mouseReleased(MouseEvent e)
{
if (isButtonColumnEditor
&& table.isEditing())
table.getCellEditor().stopCellEditing();
public void mouseReleased(MouseEvent e) {
if (isButtonColumnEditor
&& table.isEditing()) {
table.getCellEditor().stopCellEditing();
}
isButtonColumnEditor = false;
isButtonColumnEditor = false;
}
@Override
public void mouseClicked(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {}
public void mouseExited(MouseEvent e) {
}
}

View File

@ -144,9 +144,9 @@ public class Case implements SleuthkitCase.ErrorObserver {
*/
REPORT_ADDED,
/**
* Name for the property change event when a report is deleted
* from the case. Both the old value and the new value supplied by the
* event object are null.
* Name for the property change event when a report is deleted from the
* case. Both the old value and the new value supplied by the event
* object are null.
*/
REPORT_DELETED,
/**
@ -310,9 +310,9 @@ public class Case implements SleuthkitCase.ErrorObserver {
* Creates a new case (create the XML config file and database)
*
* @param caseDir The directory to store case data in. Will be created if
* it
* doesn't already exist. If it exists, it should have all of the needed sub
* dirs that createCaseDirectory() will create.
* it doesn't already exist. If it exists, it should have
* all of the needed sub dirs that createCaseDirectory()
* will create.
* @param caseName the name of case
* @param caseNumber the case number
* @param examiner the examiner for this case
@ -1244,8 +1244,7 @@ public class Case implements SleuthkitCase.ErrorObserver {
*
* @param localPath The path of the report file, must be in the case
* directory or one of its subdirectories.
* @param sourceModuleName The name of the module that created the
* report.
* @param sourceModuleName The name of the module that created the report.
* @param reportName The report name, may be empty.
*
* @return A Report data transfer object (DTO) for the new row.
@ -1277,9 +1276,10 @@ public class Case implements SleuthkitCase.ErrorObserver {
* Deletes reports from the case - deletes it from the disk as well as the
* database.
*
* @param reports Collection of Report to be deleted from the case.
* @param reports Collection of Report to be deleted from the case.
* @param deleteFromDisk Set true to perform reports file deletion from
* disk.
* disk.
*
* @throws TskCoreException
*/
public void deleteReports(Collection<? extends Report> reports, boolean deleteFromDisk) throws TskCoreException {

View File

@ -16,7 +16,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
import java.awt.Component;
@ -38,7 +37,7 @@ import org.openide.util.actions.Presenter;
* The action to close the current Case. This class should be disabled on
* creation and it will be enabled on new case creation or case opened.
*/
final class CaseCloseAction extends CallableSystemAction implements Presenter.Toolbar{
final class CaseCloseAction extends CallableSystemAction implements Presenter.Toolbar {
JButton toolbarButton = new JButton();
@ -64,18 +63,20 @@ import org.openide.util.actions.Presenter;
/**
* Closes the current opened case.
*
* @param e the action event for this method
* @param e the action event for this method
*/
@Override
public void actionPerformed(ActionEvent e) {
if (Case.existsCurrentCase() == false)
if (Case.existsCurrentCase() == false) {
return;
}
Case result = Case.getCurrentCase();
if(!MessageNotifyUtil.Message.confirm("Are you sure you want to close current case?"))
if (!MessageNotifyUtil.Message.confirm("Are you sure you want to close current case?")) {
return;
}
try {
result.closeCase();
EventQueue.invokeLater(new Runnable() {
@ -90,7 +91,8 @@ import org.openide.util.actions.Presenter;
}
/**
* This method does nothing. Use the "actionPerformed(ActionEvent e)" instead of this method.
* This method does nothing. Use the "actionPerformed(ActionEvent e)"
* instead of this method.
*/
@Override
public void performAction() {
@ -108,18 +110,18 @@ import org.openide.util.actions.Presenter;
/**
* Gets the HelpCtx associated with implementing object
*
*
* @return HelpCtx or HelpCtx.DEFAULT_HELP
*/
@Override
public HelpCtx getHelpCtx() {
return HelpCtx.DEFAULT_HELP;
return HelpCtx.DEFAULT_HELP;
}
/**
* Returns the toolbar component of this action
*
* @return component the toolbar button
* @return component the toolbar button
*/
@Override
public Component getToolbarPresenter() {
@ -132,10 +134,10 @@ import org.openide.util.actions.Presenter;
/**
* Set this action to be enabled/disabled
*
* @param value whether to enable this action or not
* @param value whether to enable this action or not
*/
@Override
public void setEnabled(boolean value){
public void setEnabled(boolean value) {
super.setEnabled(value);
toolbarButton.setEnabled(value);
}

View File

@ -16,31 +16,37 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
/**
* NOTE: NOTHING ACTUALLY USES THIS
*
*
* The interface for the classes that edit the case configuration file
*/
//TODO: check that this can just be deleted.
interface CaseConfigFileInterface {
public void open(String conFilePath) throws Exception; // opens the confiuation store (XML, DB...)
public void writeFile() throws Exception; // writes out the configuration to store
public void close() throws Exception; // close and clear the document handler
// public int[] getImageIDs() throws Exception; // returns a list of image IDs and names
// public int getNextImageID() throws Exception; // returns the next free ID to be assigned to new image, and increments the internal counter
// all the get and set methods
public String getCaseName() throws Exception; // get the case name
public void setCaseName(String caseName) throws Exception; // set the case name
public String getCaseNumber() throws Exception; // get the case number
public void setCaseNumber(String caseNumber) throws Exception; // set the case number
public String getCaseExaminer() throws Exception; // get the examiner
public void setCaseExaminer(String examiner) throws Exception; // set the examiner
// public void getXXX(); // methods to get the case attributes
// public void setXXX(); // methods to set the case attributes
}

View File

@ -16,12 +16,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
import java.awt.event.ActionEvent;
import java.io.File;
import java.util.logging.Level;import org.sleuthkit.autopsy.coreutils.Logger;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.Action;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
@ -57,10 +57,12 @@ import org.openide.util.actions.CallableSystemAction;
* The action to delete the current Case. This class should be disabled on
* creation and it will be enabled on new case creation or case opened.
*/
final class CaseDeleteAction extends CallableSystemAction {
final class CaseDeleteAction extends CallableSystemAction {
private JPanel caller; // for error handling
private static final Logger logger = Logger.getLogger(CaseDeleteAction.class.getName());
/**
@ -73,6 +75,7 @@ import org.openide.util.actions.CallableSystemAction;
/**
* Deletes the current opened case.
*
* @param e
*/
@Override
@ -81,24 +84,23 @@ import org.openide.util.actions.CallableSystemAction;
File configFile = new File(currentCase.getConfigFilePath());
File caseFolder = new File(configFile.getParent());
String caseName = currentCase.getName();
if(!caseFolder.exists()){
if (!caseFolder.exists()) {
// throw an error
logger.log(Level.WARNING, "Couldn't delete case.", new Exception("The case directory doesn't exist.")); //NON-NLS
}
else{
} else {
// show the confirmation first to close the current case and open the "New Case" wizard panel
String closeCurrentCase = NbBundle.getMessage(this.getClass(), "CaseDeleteAction.closeConfMsg.text", caseName, caseFolder.getPath());
String closeCurrentCase = NbBundle.getMessage(this.getClass(), "CaseDeleteAction.closeConfMsg.text", caseName, caseFolder.getPath());
NotifyDescriptor d = new NotifyDescriptor.Confirmation(closeCurrentCase,
NbBundle.getMessage(this.getClass(),
"CaseDeleteAction.closeConfMsg.title"),
NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
NbBundle.getMessage(this.getClass(),
"CaseDeleteAction.closeConfMsg.title"),
NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
d.setValue(NotifyDescriptor.NO_OPTION);
Object res = DialogDisplayer.getDefault().notify(d);
if(res != null && res == DialogDescriptor.YES_OPTION){
if (res != null && res == DialogDescriptor.YES_OPTION) {
boolean success = false;
try {
Case.getCurrentCase().deleteCase(caseFolder); // delete the current case
success = true;
@ -107,26 +109,26 @@ import org.openide.util.actions.CallableSystemAction;
}
// show notification whether the case has been deleted or it failed to delete...
if(!success){
if (!success) {
JOptionPane.showMessageDialog(caller,
NbBundle.getMessage(this.getClass(),
"CaseDeleteAction.msgDlg.fileInUse.msg"),
NbBundle.getMessage(this.getClass(),
"CaseDeleteAction.msgDlg.fileInUse.title"),
JOptionPane.ERROR_MESSAGE); // throw an error
}
else{
NbBundle.getMessage(this.getClass(),
"CaseDeleteAction.msgDlg.fileInUse.msg"),
NbBundle.getMessage(this.getClass(),
"CaseDeleteAction.msgDlg.fileInUse.title"),
JOptionPane.ERROR_MESSAGE); // throw an error
} else {
CasePropertiesAction.closeCasePropertiesWindow(); // because the "Delete Case" button is in the "CaseProperties" window, we have to close that window when we delete the case.
JOptionPane.showMessageDialog(caller, NbBundle.getMessage(this.getClass(),
"CaseDeleteAction.msgDlg.caseDelete.msg",
caseName));
"CaseDeleteAction.msgDlg.caseDelete.msg",
caseName));
}
}
}
}
/**
* This method does nothing. Use the "actionPerformed(ActionEvent e)" instead of this method.
* This method does nothing. Use the "actionPerformed(ActionEvent e)"
* instead of this method.
*/
@Override
public void performAction() {
@ -135,6 +137,7 @@ import org.openide.util.actions.CallableSystemAction;
/**
* Gets the name of this action. This may be presented as an item in a menu.
*
* @return actionName
*/
@Override
@ -144,6 +147,7 @@ import org.openide.util.actions.CallableSystemAction;
/**
* Gets the HelpCtx associated with implementing object
*
* @return HelpCtx or HelpCtx.DEFAULT_HELP
*/
@Override

View File

@ -16,7 +16,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
import java.awt.event.ActionEvent;
@ -35,6 +34,7 @@ public final class CaseNewAction implements CaseNewActionInterface {
/**
* Calls the "New Case" wizard panel action.
*
* @param e
*/
@Override

View File

@ -16,8 +16,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
import java.awt.event.ActionListener;

View File

@ -50,7 +50,7 @@ public final class CaseOpenAction implements ActionListener {
public CaseOpenAction() {
autFilter = new FileNameExtensionFilter(
NbBundle.getMessage(CaseOpenAction.class, "CaseOpenAction.autFilter.title", Version.getName(),
Case.CASE_DOT_EXTENSION),
Case.CASE_DOT_EXTENSION),
Case.CASE_EXTENSION);
fc.setDragEnabled(false);
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
@ -80,11 +80,11 @@ public final class CaseOpenAction implements ActionListener {
// check if the file exists
if (!new File(path).exists()) {
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(this.getClass(),
"CaseOpenAction.msgDlg.fileNotExist.msg"),
NbBundle.getMessage(this.getClass(),
"CaseOpenAction.msgDlg.fileNotExist.title"),
JOptionPane.ERROR_MESSAGE);
NbBundle.getMessage(this.getClass(),
"CaseOpenAction.msgDlg.fileNotExist.msg"),
NbBundle.getMessage(this.getClass(),
"CaseOpenAction.msgDlg.fileNotExist.title"),
JOptionPane.ERROR_MESSAGE);
this.actionPerformed(e); // show the dialog box again
} else {
// try to close Startup window if there's one
@ -98,12 +98,12 @@ public final class CaseOpenAction implements ActionListener {
Case.open(path); // open the case
} catch (CaseActionException ex) {
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(this.getClass(),
"CaseOpenAction.msgDlg.cantOpenCase.msg", path,
ex.getMessage()),
NbBundle.getMessage(this.getClass(),
"CaseOpenAction.msgDlg.cantOpenCase.title"),
JOptionPane.ERROR_MESSAGE);
NbBundle.getMessage(this.getClass(),
"CaseOpenAction.msgDlg.cantOpenCase.msg", path,
ex.getMessage()),
NbBundle.getMessage(this.getClass(),
"CaseOpenAction.msgDlg.cantOpenCase.title"),
JOptionPane.ERROR_MESSAGE);
logger.log(Level.WARNING, "Error opening case in folder " + path, ex); //NON-NLS
StartupWindowProvider.getInstance().open();

View File

@ -16,7 +16,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
import java.awt.Dimension;
@ -40,7 +39,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
*
* @author jantonius
*/
final class CasePropertiesAction extends CallableSystemAction {
final class CasePropertiesAction extends CallableSystemAction {
private static JDialog popUpWindow;
@ -64,12 +63,11 @@ import org.sleuthkit.autopsy.coreutils.Logger;
final JFrame frame = new JFrame(title);
popUpWindow = new JDialog(frame, title, true); // to make the popUp Window to be modal
// get the information that needed
Case currentCase = Case.getCurrentCase();
String crDate = currentCase.getCreatedDate();
String caseDir = currentCase.getCaseDirectory();
// put the image paths information into hashmap
Map<Long, String> imgPaths = Case.getImagePaths(currentCase.getSleuthkitCase());
@ -104,6 +102,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Gets the name of this action. This may be presented as an item in a menu.
*
* @return actionName
*/
@Override
@ -113,6 +112,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Gets the HelpCtx associated with implementing object
*
* @return HelpCtx or HelpCtx.DEFAULT_HELP
*/
@Override

View File

@ -22,7 +22,6 @@
*
* Created on Mar 14, 2011, 1:48:20 PM
*/
package org.sleuthkit.autopsy.casemodule;
import java.awt.*;
@ -46,26 +45,26 @@ import org.openide.util.actions.CallableSystemAction;
*
* @author jantonius
*/
class CasePropertiesForm extends javax.swing.JPanel{
class CasePropertiesForm extends javax.swing.JPanel {
Case current = null;
private static JPanel caller; // panel for error
// Shrink a path to fit in targetLength (if necessary), by replaceing part
// of the path with "...". Ex: "C:\Users\bob\...\folder\other\Image.img"
private String shrinkPath(String path, int targetLength) {
if(path.length() > targetLength){
if (path.length() > targetLength) {
String fill = "...";
int partsLength = targetLength - fill.length();
String front = path.substring(0, partsLength/4);
String front = path.substring(0, partsLength / 4);
int frontSep = front.lastIndexOf(File.separatorChar);
if (frontSep != -1) {
front = front.substring(0, frontSep+1);
front = front.substring(0, frontSep + 1);
}
String back = path.substring(partsLength*3/4);
String back = path.substring(partsLength * 3 / 4);
int backSep = back.indexOf(File.separatorChar);
if (backSep != -1) {
back = back.substring(backSep);
@ -75,9 +74,10 @@ class CasePropertiesForm extends javax.swing.JPanel{
return path;
}
}
/** Creates new form CasePropertiesForm */
/**
* Creates new form CasePropertiesForm
*/
CasePropertiesForm(Case currentCase, String crDate, String caseDir, Map<Long, String> imgPaths) {
initComponents();
caseNameTextField.setText(currentCase.getName());
@ -89,37 +89,35 @@ class CasePropertiesForm extends javax.swing.JPanel{
current = currentCase;
int totalImages = imgPaths.size();
// create the headers and add all the rows
String[] headers = {"Path"}; //NON-NLS
String[][] rows = new String[totalImages][];
int i = 0;
for(long key : imgPaths.keySet()){
for (long key : imgPaths.keySet()) {
String path = imgPaths.get(key);
String shortenPath = shrinkPath(path, 70);
rows[i++] = new String[]{shortenPath};
}
// create the table inside with the imgPaths information
DefaultTableModel model = new DefaultTableModel(rows, headers)
{
DefaultTableModel model = new DefaultTableModel(rows, headers) {
@Override
// make the cells in the FileContentTable "read only"
public boolean isCellEditable(int row, int column){
public boolean isCellEditable(int row, int column) {
return false;
//return column == lastColumn; // make the last column (Remove button), only the editable
}
};
imagesTable.setModel(model);
// // set the size of the remove column
// TableColumn removeCol = imagesTable.getColumnModel().getColumn(lastColumn);
// removeCol.setPreferredWidth(75);
// removeCol.setMaxWidth(75);
// removeCol.setMinWidth(75);
// removeCol.setResizable(false);
// // create the delete action to remove the image from the current case
// Action delete = new AbstractAction()
// {
@ -158,7 +156,8 @@ class CasePropertiesForm extends javax.swing.JPanel{
// buttonColumn.setMnemonic(KeyEvent.VK_D);
}
/** This method is called from within the constructor to initialize the form.
/**
* 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.
*/
@ -355,7 +354,7 @@ class CasePropertiesForm extends javax.swing.JPanel{
/**
* Updates the case name.
*
* @param evt The action event
* @param evt The action event
*/
private void updateCaseNameButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_updateCaseNameButtonActionPerformed
String oldCaseName = Case.getCurrentCase().getName();
@ -364,47 +363,45 @@ class CasePropertiesForm extends javax.swing.JPanel{
//String newPath = caseDirTextArea.getText() + File.separator + newCaseName + ".aut";
// check if the old and new case name is not equal
if(!oldCaseName.equals(newCaseName)){
if (!oldCaseName.equals(newCaseName)) {
// check if the case name is empty
if(newCaseName.trim().equals("")){
if (newCaseName.trim().equals("")) {
JOptionPane.showMessageDialog(caller,
NbBundle.getMessage(this.getClass(),
"CasePropertiesForm.updateCaseName.msgDlg.empty.msg"),
NbBundle.getMessage(this.getClass(),
"CasePropertiesForm.updateCaseName.msgDlg.empty.title"),
JOptionPane.ERROR_MESSAGE);
}
else{
NbBundle.getMessage(this.getClass(),
"CasePropertiesForm.updateCaseName.msgDlg.empty.msg"),
NbBundle.getMessage(this.getClass(),
"CasePropertiesForm.updateCaseName.msgDlg.empty.title"),
JOptionPane.ERROR_MESSAGE);
} else {
// check if case Name contain one of this following symbol:
// \ / : * ? " < > |
if(newCaseName.contains("\\") || newCaseName.contains("/") || newCaseName.contains(":") ||
newCaseName.contains("*") || newCaseName.contains("?") || newCaseName.contains("\"") ||
newCaseName.contains("<") || newCaseName.contains(">") || newCaseName.contains("|")){
if (newCaseName.contains("\\") || newCaseName.contains("/") || newCaseName.contains(":")
|| newCaseName.contains("*") || newCaseName.contains("?") || newCaseName.contains("\"")
|| newCaseName.contains("<") || newCaseName.contains(">") || newCaseName.contains("|")) {
String errorMsg = NbBundle
.getMessage(this.getClass(), "CasePropertiesForm.updateCaseName.msgDlg.invalidSymbols.msg");
JOptionPane.showMessageDialog(caller, errorMsg,
NbBundle.getMessage(this.getClass(),
"CasePropertiesForm.updateCaseName.msgDlg.invalidSymbols.title"),
JOptionPane.ERROR_MESSAGE);
}
else{
NbBundle.getMessage(this.getClass(),
"CasePropertiesForm.updateCaseName.msgDlg.invalidSymbols.title"),
JOptionPane.ERROR_MESSAGE);
} else {
// ask for the confirmation first
String confMsg = NbBundle
.getMessage(this.getClass(), "CasePropertiesForm.updateCaseName.confMsg.msg", oldCaseName,
newCaseName);
newCaseName);
NotifyDescriptor d = new NotifyDescriptor.Confirmation(confMsg,
NbBundle.getMessage(this.getClass(),
"CasePropertiesForm.updateCaseName.confMsg.title"),
NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
NbBundle.getMessage(this.getClass(),
"CasePropertiesForm.updateCaseName.confMsg.title"),
NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
d.setValue(NotifyDescriptor.NO_OPTION);
Object res = DialogDisplayer.getDefault().notify(d);
if(res != null && res == DialogDescriptor.YES_OPTION){
if (res != null && res == DialogDescriptor.YES_OPTION) {
// if user select "Yes"
String oldPath = current.getConfigFilePath();
try {
current.updateCaseName(oldCaseName, oldPath , newCaseName, oldPath);
current.updateCaseName(oldCaseName, oldPath, newCaseName, oldPath);
} catch (Exception ex) {
Logger.getLogger(CasePropertiesForm.class.getName()).log(Level.WARNING, "Error: problem updating case name.", ex); //NON-NLS
}
@ -418,13 +415,12 @@ class CasePropertiesForm extends javax.swing.JPanel{
CallableSystemAction.get(CaseDeleteAction.class).actionPerformed(evt);
}//GEN-LAST:event_deleteCaseButtonActionPerformed
/**
* Sets the listener for the OK button
*
* @param e The action listener
* @param e The action listener
*/
public void setOKButtonActionListener(ActionListener e){
public void setOKButtonActionListener(ActionListener e) {
OKButton.addActionListener(e);
}

View File

@ -16,7 +16,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
import java.awt.*;
@ -59,10 +58,10 @@ public class CueBannerPanel extends javax.swing.JPanel {
}
}
/** 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.
/**
* 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
@ -209,14 +208,14 @@ public class CueBannerPanel extends javax.swing.JPanel {
int h = recentCasesWindow.getSize().height;
// set the location of the popUp Window on the center of the screen
recentCasesWindow.setLocation((screenDimension.width - w)/2, (screenDimension.height - h)/2);
recentCasesWindow.setLocation((screenDimension.width - w) / 2, (screenDimension.height - h) / 2);
OpenRecentCasePanel welcomeWindow = OpenRecentCasePanel.getInstance();
// add the command to close the window to the button on the Volume Detail Panel
welcomeWindow.setCloseButtonActionListener( new ActionListener(){
welcomeWindow.setCloseButtonActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e){
public void actionPerformed(ActionEvent e) {
recentCasesWindow.dispose();
}
});
@ -228,7 +227,6 @@ public class CueBannerPanel extends javax.swing.JPanel {
recentCasesWindow.setVisible(true);
}//GEN-LAST:event_openRecentButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel autopsyLogo;
private javax.swing.JButton closeButton;
@ -244,9 +242,9 @@ public class CueBannerPanel extends javax.swing.JPanel {
/**
* Sets the Close button action listener.
*
* @param e the action listener
* @param e the action listener
*/
public void setCloseButtonActionListener(ActionListener e){
public void setCloseButtonActionListener(ActionListener e) {
closeButton.addActionListener(e);
}
@ -257,12 +255,12 @@ public class CueBannerPanel extends javax.swing.JPanel {
*/
public void setCloseButtonText(String text) {
closeButton.setText(text);
}
}
/**
* Close the open recent cases window.
*/
public static void closeOpenRecentCasesWindow(){
public static void closeOpenRecentCasesWindow() {
//startupWindow.setVisible(false);
recentCasesWindow.dispose();
}

View File

@ -16,7 +16,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
import org.openide.util.NbBundle;
@ -29,23 +28,20 @@ import javax.swing.filechooser.FileFilter;
/**
* FileFilter helper class. Matches files based on extension
*/
public class GeneralFilter extends FileFilter{
public class GeneralFilter extends FileFilter {
// Extensions & Descriptions for commonly used filters
public static final List<String> RAW_IMAGE_EXTS = Arrays.asList(new String[]{".img", ".dd", ".001", ".aa", ".raw", ".bin"}); //NON-NLS
public static final String RAW_IMAGE_DESC = NbBundle.getMessage(GeneralFilter.class, "GeneralFilter.rawImageDesc.text");
public static final List<String> ENCASE_IMAGE_EXTS = Arrays.asList(new String[]{".e01"}); //NON-NLS
public static final String ENCASE_IMAGE_DESC = NbBundle.getMessage(GeneralFilter.class,
"GeneralFilter.encaseImageDesc.text");
"GeneralFilter.encaseImageDesc.text");
private List<String> extensions;
private String desc;
public GeneralFilter(List<String> ext, String desc){
public GeneralFilter(List<String> ext, String desc) {
super();
this.extensions = ext;
this.desc = desc;
@ -54,12 +50,13 @@ public class GeneralFilter extends FileFilter{
/**
* Checks whether the given file is accepted by this filter.
*
* @param f the given file
* @return boolean return true if accepted, false otherwise
* @param f the given file
*
* @return boolean return true if accepted, false otherwise
*/
@Override
public boolean accept(File f) {
if(f.isDirectory()){
if (f.isDirectory()) {
return true;
} else {
Boolean result = false;
@ -77,7 +74,7 @@ public class GeneralFilter extends FileFilter{
/**
* Returns the description of this file filter
*
* @return desc return the description
* @return desc return the description
*/
@Override
public String getDescription() {

View File

@ -31,181 +31,190 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorCallback
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
/**
* Image data source processor.
* Handles the addition of "disk images" to Autopsy.
*
* Image data source processor. Handles the addition of "disk images" to
* Autopsy.
*
* An instance of this class is created via the Netbeans Lookup() method.
*
*
*/
@ServiceProvider(service = DataSourceProcessor.class)
public class ImageDSProcessor implements DataSourceProcessor {
static final Logger logger = Logger.getLogger(ImageDSProcessor.class.getName());
// Data source type handled by this processor
private final static String dsType = NbBundle.getMessage(ImageDSProcessor.class, "ImageDSProcessor.dsType.text");
// The Config UI panel that plugins into the Choose Data Source Wizard
private final ImageFilePanel imageFilePanel;
// The Background task that does the actual work of adding the image
private AddImageTask addImageTask;
// true of cancelled by the caller
private boolean cancelled = false;
DataSourceProcessorCallback callbackObj = null;
// set to TRUE if the image options have been set via API and config Jpanel should be ignored
private boolean imageOptionsSet = false;
// image options
private String imagePath;
private String timeZone;
private boolean noFatOrphans;
static final GeneralFilter rawFilter = new GeneralFilter(GeneralFilter.RAW_IMAGE_EXTS, GeneralFilter.RAW_IMAGE_DESC);
static final GeneralFilter encaseFilter = new GeneralFilter(GeneralFilter.ENCASE_IMAGE_EXTS, GeneralFilter.ENCASE_IMAGE_DESC);
static final List<String> allExt = new ArrayList<>();
static {
allExt.addAll(GeneralFilter.RAW_IMAGE_EXTS);
allExt.addAll(GeneralFilter.ENCASE_IMAGE_EXTS);
}
static final String allDesc = NbBundle.getMessage(ImageDSProcessor.class, "ImageDSProcessor.allDesc.text");
static final GeneralFilter allFilter = new GeneralFilter(allExt, allDesc);
static final List<FileFilter> filtersList = new ArrayList<>();
static {
filtersList.add(allFilter);
filtersList.add(rawFilter);
filtersList.add(encaseFilter);
}
/*
* A no argument constructor is required for the NM lookup() method to create an object
* A no argument constructor is required for the NM lookup() method to
* create an object
*/
public ImageDSProcessor() {
// Create the config panel
imageFilePanel = ImageFilePanel.createInstance(ImageDSProcessor.class.getName(), filtersList);
imageFilePanel = ImageFilePanel.createInstance(ImageDSProcessor.class.getName(), filtersList);
}
// this static method is used by the wizard to determine dsp type for 'core' data source processors
public static String getType() {
return dsType;
}
/**
* Returns the Data source type (string) handled by this DSP
*
* @return String the data source type
**/
*
*/
@Override
public String getDataSourceType() {
return dsType;
}
/**
* Returns the JPanel for collecting the Data source information
*
* @return JPanel the config panel
**/
@Override
*
*/
@Override
public JPanel getPanel() {
imageFilePanel.readSettings();
imageFilePanel.select();
return imageFilePanel;
}
imageFilePanel.readSettings();
imageFilePanel.select();
return imageFilePanel;
}
/**
* Validates the data collected by the JPanel
*
* @return String returns NULL if success, error string if there is any errors
**/
@Override
public boolean isPanelValid() {
return imageFilePanel.validatePanel();
}
/**
* Runs the data source processor.
* This must kick off processing the data source in background
* @return String returns NULL if success, error string if there is any
* errors
*
* @param progressMonitor Progress monitor to report progress during processing
* @param cbObj callback to call when processing is done.
**/
@Override
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback cbObj) {
callbackObj = cbObj;
cancelled = false;
if (!imageOptionsSet)
{
//tell the panel to save the current settings
imageFilePanel.storeSettings();
// get the image options from the panel
imagePath = imageFilePanel.getContentPaths();
timeZone = imageFilePanel.getTimeZone();
noFatOrphans = imageFilePanel.getNoFatOrphans();
}
addImageTask = new AddImageTask(imagePath, timeZone, noFatOrphans, progressMonitor, cbObj);
new Thread(addImageTask).start();
}
*/
@Override
public boolean isPanelValid() {
return imageFilePanel.validatePanel();
}
/**
* Runs the data source processor. This must kick off processing the data
* source in background
*
* @param progressMonitor Progress monitor to report progress during
* processing
* @param cbObj callback to call when processing is done.
*
*/
@Override
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback cbObj) {
callbackObj = cbObj;
cancelled = false;
if (!imageOptionsSet) {
//tell the panel to save the current settings
imageFilePanel.storeSettings();
// get the image options from the panel
imagePath = imageFilePanel.getContentPaths();
timeZone = imageFilePanel.getTimeZone();
noFatOrphans = imageFilePanel.getNoFatOrphans();
}
addImageTask = new AddImageTask(imagePath, timeZone, noFatOrphans, progressMonitor, cbObj);
new Thread(addImageTask).start();
}
/**
* Cancel the data source processing
**/
@Override
public void cancel() {
cancelled = true;
addImageTask.cancelTask();
}
/**
* Reset the data source processor
**/
@Override
public void reset() {
// reset the config panel
imageFilePanel.reset();
// reset state
imageOptionsSet = false;
imagePath = null;
timeZone = null;
noFatOrphans = false;
}
/**
* Sets the data source options externally.
* To be used by a client that does not have a UI and does not use the JPanel to
* collect this information from a user.
*
* @param imgPath path to thew image or first image
* @param tz timeZone
* @param noFat whether to parse FAT orphans
**/
public void setDataSourceOptions(String imgPath, String tz, boolean noFat) {
this.imagePath = imgPath;
this.timeZone = tz;
this.noFatOrphans = noFat;
imageOptionsSet = true;
}
*
*/
@Override
public void cancel() {
cancelled = true;
addImageTask.cancelTask();
}
/**
* Reset the data source processor
*
*/
@Override
public void reset() {
// reset the config panel
imageFilePanel.reset();
// reset state
imageOptionsSet = false;
imagePath = null;
timeZone = null;
noFatOrphans = false;
}
/**
* Sets the data source options externally. To be used by a client that does
* not have a UI and does not use the JPanel to collect this information
* from a user.
*
* @param imgPath path to thew image or first image
* @param tz timeZone
* @param noFat whether to parse FAT orphans
*
*/
public void setDataSourceOptions(String imgPath, String tz, boolean noFat) {
this.imagePath = imgPath;
this.timeZone = tz;
this.noFatOrphans = noFat;
imageOptionsSet = true;
}
}

View File

@ -42,53 +42,55 @@ import org.sleuthkit.autopsy.coreutils.Logger;
* ImageTypePanel for adding an image file such as .img, .E0x, .00x, etc.
*/
public class ImageFilePanel extends JPanel implements DocumentListener {
private final String PROP_LASTIMAGE_PATH = "LBL_LastImage_PATH"; //NON-NLS
private static final Logger logger = Logger.getLogger(ImageFilePanel.class.getName());
private PropertyChangeSupport pcs = null;
private JFileChooser fc = new JFileChooser();
// Externally supplied name is used to store settings
private String contextName;
/**
* Creates new form ImageFilePanel
* @param context a string context name used to read/store last used settings
* @param fileChooserFilters a list of filters to be used with the FileChooser
*
* @param context a string context name used to read/store last
* used settings
* @param fileChooserFilters a list of filters to be used with the
* FileChooser
*/
private ImageFilePanel(String context, List<FileFilter> fileChooserFilters) {
initComponents();
fc.setDragEnabled(false);
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
fc.setMultiSelectionEnabled(false);
boolean firstFilter = true;
for (FileFilter filter: fileChooserFilters ) {
for (FileFilter filter : fileChooserFilters) {
if (firstFilter) { // set the first on the list as the default selection
fc.setFileFilter(filter);
firstFilter = false;
}
else {
} else {
fc.addChoosableFileFilter(filter);
}
}
this.contextName = context;
pcs = new PropertyChangeSupport(this);
createTimeZoneList();
}
/**
* Creates and returns an instance of a ImageFilePanel.
*/
public static synchronized ImageFilePanel createInstance(String context, List<FileFilter> fileChooserFilters) {
ImageFilePanel instance = new ImageFilePanel(context, fileChooserFilters );
instance.postInit();
return instance;
ImageFilePanel instance = new ImageFilePanel(context, fileChooserFilters);
instance.postInit();
return instance;
}
//post-constructor initialization to properly initialize listener support
@ -96,8 +98,6 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
private void postInit() {
pathTextField.getDocument().addDocumentListener(this);
}
/**
* This method is called from within the constructor to initialize the form.
@ -194,17 +194,14 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
String path = fc.getSelectedFile().getPath();
pathTextField.setText(path);
}
try {
pcs.firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.FOCUS_NEXT.toString(), false, true);
}
catch (Exception e) {
} catch (Exception e) {
logger.log(Level.SEVERE, "ImageFilePanel listener threw exception", e); //NON-NLS
MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(), "ImageFilePanel.moduleErr"),
NbBundle.getMessage(this.getClass(), "ImageFilePanel.moduleErr.msg"),
MessageNotifyUtil.MessageType.ERROR);
NbBundle.getMessage(this.getClass(), "ImageFilePanel.moduleErr.msg"),
MessageNotifyUtil.MessageType.ERROR);
}
}//GEN-LAST:event_browseButtonActionPerformed
@ -217,9 +214,10 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
private javax.swing.JComboBox<String> timeZoneComboBox;
private javax.swing.JLabel timeZoneLabel;
// End of variables declaration//GEN-END:variables
/**
* Get the path of the user selected image.
*
* @return the image path
*/
public String getContentPaths() {
@ -236,22 +234,21 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
public String getTimeZone() {
String tz = timeZoneComboBox.getSelectedItem().toString();
return tz.substring(tz.indexOf(")") + 2).trim();
}
public boolean getNoFatOrphans() {
return noFatOrphansCheckbox.isSelected();
}
public void reset() {
//reset the UI elements to default
pathTextField.setText(null);
pathTextField.setText(null);
}
/**
* Should we enable the next button of the wizard?
*
* @return true if a proper image has been selected, false otherwise
*/
public boolean validatePanel() {
@ -259,35 +256,36 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
if (path == null || path.isEmpty()) {
return false;
}
boolean isExist = Case.pathExists(path);
boolean isPhysicalDrive = Case.isPhysicalDrive(path);
boolean isPartition = Case.isPartition(path);
return (isExist || isPhysicalDrive || isPartition);
}
public void storeSettings() {
String imagePathName = getContentPaths();
if (null != imagePathName ) {
if (null != imagePathName) {
String imagePath = imagePathName.substring(0, imagePathName.lastIndexOf(File.separator) + 1);
ModuleSettings.setConfigSetting(contextName, PROP_LASTIMAGE_PATH, imagePath);
}
}
public void readSettings() {
String lastImagePath = ModuleSettings.getConfigSetting(contextName, PROP_LASTIMAGE_PATH);
if (null != lastImagePath) {
if (!lastImagePath.isEmpty())
pathTextField.setText(lastImagePath);
}
if (!lastImagePath.isEmpty()) {
pathTextField.setText(lastImagePath);
}
}
}
/**
* Creates the drop down list for the time zones and then makes the local
* machine time zone to be selected.
*/
public void createTimeZoneList() {
public void createTimeZoneList() {
// load and add all timezone
String[] ids = SimpleTimeZone.getAvailableIDs();
for (String id : ids) {
@ -318,75 +316,73 @@ public class ImageFilePanel extends JPanel implements DocumentListener {
// set the selected timezone
timeZoneComboBox.setSelectedItem(formatted);
}
/**
* Update functions are called by the pathTextField which has this set
* as it's DocumentEventListener. Each update function fires a property change
* Update functions are called by the pathTextField which has this set as
* it's DocumentEventListener. Each update function fires a property change
* to be caught by the parent panel.
*
* @param e the event, which is ignored
*/
@Override
public void insertUpdate(DocumentEvent e) {
try {
pcs.firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), false, true);
}
catch (Exception ee) {
} catch (Exception ee) {
logger.log(Level.SEVERE, "ImageFilePanel listener threw exception", ee); //NON-NLS
MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(), "ImageFilePanel.moduleErr"),
NbBundle.getMessage(this.getClass(), "ImageFilePanel.moduleErr.msg"),
MessageNotifyUtil.MessageType.ERROR);
NbBundle.getMessage(this.getClass(), "ImageFilePanel.moduleErr.msg"),
MessageNotifyUtil.MessageType.ERROR);
}
}
@Override
public void removeUpdate(DocumentEvent e) {
public void removeUpdate(DocumentEvent e) {
try {
pcs.firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), false, true);
}
catch (Exception ee) {
pcs.firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), false, true);
} catch (Exception ee) {
logger.log(Level.SEVERE, "ImageFilePanel listener threw exception", ee); //NON-NLS
MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(), "ImageFilePanel.moduleErr"),
NbBundle.getMessage(this.getClass(), "ImageFilePanel.moduleErr.msg"),
MessageNotifyUtil.MessageType.ERROR);
NbBundle.getMessage(this.getClass(), "ImageFilePanel.moduleErr.msg"),
MessageNotifyUtil.MessageType.ERROR);
}
}
@Override
public void changedUpdate(DocumentEvent e) {
try {
pcs.firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), false, true);
}
catch (Exception ee) {
} catch (Exception ee) {
logger.log(Level.SEVERE, "ImageFilePanel listener threw exception", ee); //NON-NLS
MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(), "ImageFilePanel.moduleErr"),
NbBundle.getMessage(this.getClass(), "ImageFilePanel.moduleErr.msg"),
MessageNotifyUtil.MessageType.ERROR);
NbBundle.getMessage(this.getClass(), "ImageFilePanel.moduleErr.msg"),
MessageNotifyUtil.MessageType.ERROR);
}
}
/**
* Set the focus to the pathTextField.
*/
public void select() {
pathTextField.requestFocusInWindow();
}
@Override
public synchronized void addPropertyChangeListener(PropertyChangeListener pcl) {
super.addPropertyChangeListener(pcl);
super.addPropertyChangeListener(pcl);
if (pcs == null) {
pcs = new PropertyChangeSupport(this);
}
if (pcs == null) {
pcs = new PropertyChangeSupport(this);
}
pcs.addPropertyChangeListener(pcl);
}
@Override
public void removePropertyChangeListener(PropertyChangeListener pcl) {
super.removePropertyChangeListener(pcl);
super.removePropertyChangeListener(pcl);
pcs.removePropertyChangeListener(pcl);
}

View File

@ -16,7 +16,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
import javax.swing.JPanel;
@ -28,150 +27,160 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessorProgress
import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
import org.sleuthkit.autopsy.coreutils.Logger;
@ServiceProvider(service = DataSourceProcessor.class)
public class LocalDiskDSProcessor implements DataSourceProcessor {
public class LocalDiskDSProcessor implements DataSourceProcessor {
static final Logger logger = Logger.getLogger(ImageDSProcessor.class.getName());
// Data source type handled by this processor
private static final String dsType = NbBundle.getMessage(LocalDiskDSProcessor.class, "LocalDiskDSProcessor.dsType.text");
private static final String dsType = NbBundle.getMessage(LocalDiskDSProcessor.class, "LocalDiskDSProcessor.dsType.text");
// The Config UI panel that plugins into the Choose Data Source Wizard
private final LocalDiskPanel localDiskPanel;
// The Background task that does the actual work of adding the local Disk
// Adding a local disk is exactly same as adding an Image.
private AddImageTask addDiskTask;
// true if cancelled by the caller
private boolean cancelled = false;
DataSourceProcessorCallback callbackObj = null;
// set to TRUE if the image options have been set via API and config Jpanel should be ignored
private boolean localDiskOptionsSet = false;
// data source options
private String localDiskPath;
private String timeZone;
private boolean noFatOrphans;
/*
* A no argument constructor is required for the NM lookup() method to create an object
/*
* A no argument constructor is required for the NM lookup() method to
* create an object
*/
public LocalDiskDSProcessor() {
// Create the config panel
localDiskPanel = LocalDiskPanel.getDefault();
localDiskPanel = LocalDiskPanel.getDefault();
}
// this static method is used by the wizard to determine dsp type for 'core' data source processors
public static String getType() {
return dsType;
}
/**
* Returns the Data source type (string) handled by this DSP
*
* @return String the data source type
**/
*
*/
@Override
public String getDataSourceType() {
return dsType;
}
/**
* Returns the JPanel for collecting the Data source information
*
* @return JPanel the config panel
**/
@Override
*
*/
@Override
public JPanel getPanel() {
localDiskPanel.select();
return localDiskPanel;
}
localDiskPanel.select();
return localDiskPanel;
}
/**
* Validates the data collected by the JPanel
*
* @return String returns NULL if success, error string if there is any errors
**/
@Override
public boolean isPanelValid() {
return localDiskPanel.validatePanel();
}
/**
* Runs the data source processor.
* This must kick off processing the data source in background
* @return String returns NULL if success, error string if there is any
* errors
*
* @param progressMonitor Progress monitor to report progress during processing
* @param cbObj callback to call when processing is done.
**/
@Override
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback cbObj) {
callbackObj = cbObj;
cancelled = false;
if (!localDiskOptionsSet) {
// get the image options from the panel
localDiskPath = localDiskPanel.getContentPaths();
timeZone = localDiskPanel.getTimeZone();
noFatOrphans = localDiskPanel.getNoFatOrphans();
}
addDiskTask = new AddImageTask(localDiskPath, timeZone, noFatOrphans, progressMonitor, cbObj);
new Thread(addDiskTask).start();
}
/**
*/
@Override
public boolean isPanelValid() {
return localDiskPanel.validatePanel();
}
/**
* Runs the data source processor. This must kick off processing the data
* source in background
*
* @param progressMonitor Progress monitor to report progress during
* processing
* @param cbObj callback to call when processing is done.
*
*/
@Override
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback cbObj) {
callbackObj = cbObj;
cancelled = false;
if (!localDiskOptionsSet) {
// get the image options from the panel
localDiskPath = localDiskPanel.getContentPaths();
timeZone = localDiskPanel.getTimeZone();
noFatOrphans = localDiskPanel.getNoFatOrphans();
}
addDiskTask = new AddImageTask(localDiskPath, timeZone, noFatOrphans, progressMonitor, cbObj);
new Thread(addDiskTask).start();
}
/**
* Cancel the data source processing
**/
@Override
public void cancel() {
cancelled = true;
addDiskTask.cancelTask();
}
/**
* Reset the data source processor
**/
@Override
public void reset() {
// reset the config panel
localDiskPanel.reset();
// reset state
localDiskOptionsSet = false;
localDiskPath = null;
timeZone = null;
noFatOrphans = false;
}
/**
* Sets the data source options externally.
* To be used by a client that does not have a UI and does not use the JPanel to
* collect this information from a user.
*
* @param diskPath path to the local disk
* @param tz time zone
* @param noFat whether to parse FAT orphans
**/
public void setDataSourceOptions(String diskPath, String tz, boolean noFat) {
this.localDiskPath = diskPath;
this.timeZone = tz;
this.noFatOrphans = noFat;
localDiskOptionsSet = true;
}
*
*/
@Override
public void cancel() {
cancelled = true;
addDiskTask.cancelTask();
}
/**
* Reset the data source processor
*
*/
@Override
public void reset() {
// reset the config panel
localDiskPanel.reset();
// reset state
localDiskOptionsSet = false;
localDiskPath = null;
timeZone = null;
noFatOrphans = false;
}
/**
* Sets the data source options externally. To be used by a client that does
* not have a UI and does not use the JPanel to collect this information
* from a user.
*
* @param diskPath path to the local disk
* @param tz time zone
* @param noFat whether to parse FAT orphans
*
*/
public void setDataSourceOptions(String diskPath, String tz, boolean noFat) {
this.localDiskPath = diskPath;
this.timeZone = tz;
this.noFatOrphans = noFat;
localDiskOptionsSet = true;
}
}

View File

@ -218,8 +218,8 @@ final class LocalDiskPanel extends JPanel {
}
/**
* Should we enable the wizard's next button?
* Always return true because we control the possible selections.
* Should we enable the wizard's next button? Always return true because we
* control the possible selections.
*
* @return true
*/
@ -313,7 +313,7 @@ final class LocalDiskPanel extends JPanel {
//private String SELECT = "Select a local disk:";
private String LOADING = NbBundle.getMessage(this.getClass(), "LocalDiskPanel.localDiskModel.loading.msg");
private String NO_DRIVES = NbBundle.getMessage(this.getClass(), "LocalDiskPanel.localDiskModel.nodrives.msg");
LocalDiskThread worker = null;
private void loadDisks() {
@ -349,8 +349,8 @@ final class LocalDiskPanel extends JPanel {
} catch (Exception e) {
logger.log(Level.SEVERE, "LocalDiskPanel listener threw exception", e); //NON-NLS
MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(), "LocalDiskPanel.moduleErr"),
NbBundle.getMessage(this.getClass(), "LocalDiskPanel.moduleErr.msg"),
MessageNotifyUtil.MessageType.ERROR);
NbBundle.getMessage(this.getClass(), "LocalDiskPanel.moduleErr.msg"),
MessageNotifyUtil.MessageType.ERROR);
}
}
}
@ -362,8 +362,7 @@ final class LocalDiskPanel extends JPanel {
return NO_DRIVES;
}
return selected;
}
else {
} else {
return LOADING;
}
}
@ -375,8 +374,7 @@ final class LocalDiskPanel extends JPanel {
return 1;
}
return disks.size();
}
else {
} else {
return 1;
}
}
@ -388,8 +386,7 @@ final class LocalDiskPanel extends JPanel {
return NO_DRIVES;
}
return disks.get(index);
}
else {
} else {
return LOADING;
}
}
@ -453,19 +450,19 @@ final class LocalDiskPanel extends JPanel {
errorLabel.setText(
NbBundle.getMessage(this.getClass(), "LocalDiskPanel.errLabel.disksNotDetected.text"));
errorLabel.setToolTipText(NbBundle.getMessage(this.getClass(),
"LocalDiskPanel.errLabel.disksNotDetected.toolTipText"));
"LocalDiskPanel.errLabel.disksNotDetected.toolTipText"));
} else {
errorLabel.setText(
NbBundle.getMessage(this.getClass(), "LocalDiskPanel.errLabel.drivesNotDetected.text"));
errorLabel.setToolTipText(NbBundle.getMessage(this.getClass(),
"LocalDiskPanel.errLabel.drivesNotDetected.toolTipText"));
"LocalDiskPanel.errLabel.drivesNotDetected.toolTipText"));
}
diskComboBox.setEnabled(false);
} else if (physicalDrives.isEmpty()) {
errorLabel.setText(
NbBundle.getMessage(this.getClass(), "LocalDiskPanel.errLabel.someDisksNotDetected.text"));
errorLabel.setToolTipText(NbBundle.getMessage(this.getClass(),
"LocalDiskPanel.errLabel.someDisksNotDetected.toolTipText"));
"LocalDiskPanel.errLabel.someDisksNotDetected.toolTipText"));
}
}
@ -483,7 +480,7 @@ final class LocalDiskPanel extends JPanel {
if (!this.isCancelled()) {
enableNext = false;
displayErrors();
worker = null;
loadingDisks = false;

View File

@ -16,7 +16,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
import javax.swing.JPanel;
@ -30,138 +29,147 @@ import org.sleuthkit.autopsy.coreutils.Logger;
@ServiceProvider(service = DataSourceProcessor.class)
public class LocalFilesDSProcessor implements DataSourceProcessor {
static final Logger logger = Logger.getLogger(LocalFilesDSProcessor.class.getName());
// Data source type handled by this processor
private static final String dsType = NbBundle.getMessage(LocalFilesDSProcessor.class, "LocalFilesDSProcessor.dsType");
// The Config UI panel that plugins into the Choose Data Source Wizard
private final LocalFilesPanel localFilesPanel;
// The Background task that does the actual work of adding the files
private AddLocalFilesTask addFilesTask;
// true if cancelled by the caller
private boolean cancelled = false;
DataSourceProcessorCallback callbackObj = null;
// set to TRUE if the image options have been set via API and config Jpanel should be ignored
private boolean localFilesOptionsSet = false;
// data source options
private String localFilesPath;
/*
* A no argument constructor is required for the NM lookup() method to create an object
* A no argument constructor is required for the NM lookup() method to
* create an object
*/
public LocalFilesDSProcessor() {
// Create the config panel
localFilesPanel = LocalFilesPanel.getDefault();
localFilesPanel = LocalFilesPanel.getDefault();
}
// this static method is used by the wizard to determine dsp type for 'core' data source processors
public static String getType() {
return dsType;
}
/**
* Returns the Data source type (string) handled by this DSP
*
* @return String the data source type
**/
*
*/
@Override
public String getDataSourceType() {
return dsType;
}
/**
* Returns the JPanel for collecting the Data source information
*
* @return JPanel the config panel
**/
@Override
*
*/
@Override
public JPanel getPanel() {
localFilesPanel.select();
return localFilesPanel;
}
localFilesPanel.select();
return localFilesPanel;
}
/**
* Validates the data collected by the JPanel
*
* @return String returns NULL if success, error string if there is any errors
**/
@Override
public boolean isPanelValid() {
return localFilesPanel.validatePanel();
}
/**
* Runs the data source processor.
* This must kick off processing the data source in background
* @return String returns NULL if success, error string if there is any
* errors
*
* @param progressMonitor Progress monitor to report progress during processing
* @param cbObj callback to call when processing is done.
**/
@Override
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback cbObj) {
callbackObj = cbObj;
cancelled = false;
if (!localFilesOptionsSet) {
// get the selected file paths from the panel
localFilesPath = localFilesPanel.getContentPaths();
}
addFilesTask = new AddLocalFilesTask(localFilesPath, progressMonitor, cbObj);
new Thread(addFilesTask).start();
}
/**
* Cancel the data source processing
**/
@Override
public void cancel() {
cancelled = true;
addFilesTask.cancelTask();
}
/**
* Reset the data source processor
**/
@Override
public void reset() {
// reset the config panel
localFilesPanel.reset();
// reset state
localFilesOptionsSet = false;
localFilesPath = null;
*/
@Override
public boolean isPanelValid() {
return localFilesPanel.validatePanel();
}
}
/**
* Sets the data source options externally.
* To be used by a client that does not have a UI and does not use the JPanel to
* collect this information from a user.
*
* @param filesPath PATH_SEP list of paths to local files
/**
* Runs the data source processor. This must kick off processing the data
* source in background
*
* @param progressMonitor Progress monitor to report progress during
* processing
* @param cbObj callback to call when processing is done.
*
*/
@Override
public void run(DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback cbObj) {
callbackObj = cbObj;
cancelled = false;
if (!localFilesOptionsSet) {
// get the selected file paths from the panel
localFilesPath = localFilesPanel.getContentPaths();
}
addFilesTask = new AddLocalFilesTask(localFilesPath, progressMonitor, cbObj);
new Thread(addFilesTask).start();
}
/**
* Cancel the data source processing
*
*/
@Override
public void cancel() {
cancelled = true;
addFilesTask.cancelTask();
}
/**
* Reset the data source processor
*
**/
public void setDataSourceOptions(String filesPath) {
localFilesPath = filesPath;
localFilesOptionsSet = true;
}
*/
@Override
public void reset() {
// reset the config panel
localFilesPanel.reset();
// reset state
localFilesOptionsSet = false;
localFilesPath = null;
}
/**
* Sets the data source options externally. To be used by a client that does
* not have a UI and does not use the JPanel to collect this information
* from a user.
*
* @param filesPath PATH_SEP list of paths to local files
*
*
*/
public void setDataSourceOptions(String filesPath) {
localFilesPath = filesPath;
localFilesOptionsSet = true;
}
}

View File

@ -31,10 +31,11 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Add input wizard subpanel for adding local files / dirs to the case
*/
class LocalFilesPanel extends JPanel {
class LocalFilesPanel extends JPanel {
private PropertyChangeSupport pcs = null;
private Set<File> currentFiles = new TreeSet<File>(); //keep currents in a set to disallow duplicates per add
@ -42,6 +43,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
private static LocalFilesPanel instance;
public static final String FILES_SEP = ",";
private static final Logger logger = Logger.getLogger(LocalFilesPanel.class.getName());
/**
* Creates new form LocalFilesPanel
*/
@ -60,19 +62,19 @@ import org.sleuthkit.autopsy.coreutils.Logger;
private void customInit() {
localFileChooser.setMultiSelectionEnabled(true);
selectedPaths.setText("");
}
//@Override
public String getContentPaths() {
//TODO consider interface change to return list of paths instead
if (currentFiles == null) {
return "";
}
StringBuilder b = new StringBuilder();
for (File f : currentFiles) {
b.append(f.getAbsolutePath() );
b.append(f.getAbsolutePath());
b.append(FILES_SEP);
}
return b.toString();
@ -83,7 +85,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
//for the local file panel we don't need to restore the last paths used
//when the wizard restarts
}
//@Override
public String getContentType() {
return NbBundle.getMessage(this.getClass(), "LocalFilesPanel.contentType.text");
@ -98,35 +100,34 @@ import org.sleuthkit.autopsy.coreutils.Logger;
public void select() {
reset();
}
//@Override
public void reset() {
currentFiles.clear();
selectedPaths.setText("");
enableNext = false;
//pcs.firePropertyChange(AddImageWizardChooseDataSourceVisual.EVENT.UPDATE_UI.toString(), false, true);
}
@Override
public synchronized void addPropertyChangeListener(PropertyChangeListener pcl) {
super.addPropertyChangeListener(pcl);
public synchronized void addPropertyChangeListener(PropertyChangeListener pcl) {
super.addPropertyChangeListener(pcl);
if (pcs == null) {
pcs = new PropertyChangeSupport(this);
}
if (pcs == null) {
pcs = new PropertyChangeSupport(this);
}
pcs.addPropertyChangeListener(pcl);
}
@Override
public void removePropertyChangeListener(PropertyChangeListener pcl) {
super.removePropertyChangeListener(pcl);
super.removePropertyChangeListener(pcl);
pcs.removePropertyChangeListener(pcl);
}
@Override
public String toString() {
return NbBundle.getMessage(this.getClass(), "LocalFilesDSProcessor.toString.text");
@ -217,11 +218,11 @@ import org.sleuthkit.autopsy.coreutils.Logger;
private void selectButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectButtonActionPerformed
int returnVal = localFileChooser.showOpenDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File [] files = localFileChooser.getSelectedFiles();
File[] files = localFileChooser.getSelectedFiles();
for (File f : files) {
currentFiles.add(f);
}
//update label
StringBuilder allPaths = new StringBuilder();
for (File f : currentFiles) {
@ -229,31 +230,28 @@ import org.sleuthkit.autopsy.coreutils.Logger;
}
this.selectedPaths.setText(allPaths.toString());
this.selectedPaths.setToolTipText(allPaths.toString());
}
if (!currentFiles.isEmpty()) {
enableNext = true;
}
else {
} else {
enableNext = false;
}
try {
pcs.firePropertyChange(DataSourceProcessor.DSP_PANEL_EVENT.UPDATE_UI.toString(), false, true);
}
catch (Exception e) {
} catch (Exception e) {
logger.log(Level.SEVERE, "LocalFilesPanel listener threw exception", e); //NON-NLS
MessageNotifyUtil.Notify.show(NbBundle.getMessage(this.getClass(), "LocalFilesPanel.moduleErr"),
NbBundle.getMessage(this.getClass(), "LocalFilesPanel.moduleErr.msg"),
MessageNotifyUtil.MessageType.ERROR);
NbBundle.getMessage(this.getClass(), "LocalFilesPanel.moduleErr.msg"),
MessageNotifyUtil.MessageType.ERROR);
}
}//GEN-LAST:event_selectButtonActionPerformed
private void clearButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearButtonActionPerformed
reset();
}//GEN-LAST:event_clearButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables

View File

@ -65,7 +65,6 @@ class MissingImageDialog extends javax.swing.JDialog {
fc.addChoosableFileFilter(encaseFilter);
fc.setFileFilter(allFilter);
customInit();
}
@ -307,9 +306,9 @@ class MissingImageDialog extends javax.swing.JDialog {
void cancel() {
int ret = JOptionPane.showConfirmDialog(null,
NbBundle.getMessage(this.getClass(),
"MissingImageDialog.confDlg.noFileSel.msg"),
"MissingImageDialog.confDlg.noFileSel.msg"),
NbBundle.getMessage(this.getClass(),
"MissingImageDialog.confDlg.noFileSel.title"),
"MissingImageDialog.confDlg.noFileSel.title"),
JOptionPane.YES_NO_OPTION);
if (ret == JOptionPane.YES_OPTION) {
this.dispose();

View File

@ -16,7 +16,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
import org.openide.util.NbBundle;
@ -34,14 +33,14 @@ import javax.swing.event.DocumentListener;
*
* @author jantonius
*/
final class NewCaseVisualPanel1 extends JPanel implements DocumentListener{
final class NewCaseVisualPanel1 extends JPanel implements DocumentListener {
private JFileChooser fc = new JFileChooser();
private NewCaseWizardPanel1 wizPanel;
NewCaseVisualPanel1(NewCaseWizardPanel1 wizPanel) {
initComponents();
this.wizPanel = wizPanel;
this.wizPanel = wizPanel;
caseNameTextField.getDocument().addDocumentListener(this);
caseParentDirTextField.getDocument().addDocumentListener(this);
}
@ -50,7 +49,7 @@ final class NewCaseVisualPanel1 extends JPanel implements DocumentListener{
* Returns the name of the this panel. This name will be shown on the left
* panel of the "New Case" wizard panel.
*
* @return name the name of this panel
* @return name the name of this panel
*/
@Override
public String getName() {
@ -60,32 +59,33 @@ final class NewCaseVisualPanel1 extends JPanel implements DocumentListener{
/**
* Gets the case name that the user types on the case name text field.
*
* @return caseName the case name from the case name text field
* @return caseName the case name from the case name text field
*/
public String getCaseName(){
public String getCaseName() {
return this.caseNameTextField.getText();
}
/**
* Gets the base directory that the user typed on the base directory text field.
* Will add file separator if it was not added.
* Gets the base directory that the user typed on the base directory text
* field. Will add file separator if it was not added.
*
* @return baseDirectory the base directory from the case dir text field
* @return baseDirectory the base directory from the case dir text field
*/
public String getCaseParentDir(){
public String getCaseParentDir() {
String parentDir = this.caseParentDirTextField.getText();
if (parentDir.endsWith(File.separator) == false) {
parentDir = parentDir + File.separator;
}
return parentDir;
}
public JTextField getCaseParentDirTextField(){
public JTextField getCaseParentDirTextField() {
return this.caseParentDirTextField;
}
/** This method is called from within the constructor to initialize the form.
/**
* 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.
*/
@ -173,27 +173,27 @@ final class NewCaseVisualPanel1 extends JPanel implements DocumentListener{
/**
* The action when the Browse button is pressed. The browse button will pop
* up the file chooser window to choose where the user wants to save the
* up the file chooser window to choose where the user wants to save the
* case directory.
*
* @param evt the action event
* @param evt the action event
*/
private void caseDirBrowseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_caseDirBrowseButtonActionPerformed
// show the directory chooser where the case directory will be created
fc.setDragEnabled(false);
if(!caseParentDirTextField.getText().trim().equals("")){
if (!caseParentDirTextField.getText().trim().equals("")) {
fc.setCurrentDirectory(new File(caseParentDirTextField.getText()));
}
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
//fc.setSelectedFile(new File("C:\\Program Files\\"));
//disableTextField(fc); // disable all the text field on the file chooser
int returnValue = fc.showDialog((Component)evt.getSource(), NbBundle.getMessage(this.getClass(),
"NewCaseVisualPanel1.caseDirBrowse.selectButton.text"));
if(returnValue == JFileChooser.APPROVE_OPTION){
int returnValue = fc.showDialog((Component) evt.getSource(), NbBundle.getMessage(this.getClass(),
"NewCaseVisualPanel1.caseDirBrowse.selectButton.text"));
if (returnValue == JFileChooser.APPROVE_OPTION) {
String path = fc.getSelectedFile().getPath();
caseParentDirTextField.setText(path); // put the path to the textfield
}
}
}//GEN-LAST:event_caseDirBrowseButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
@ -208,10 +208,10 @@ final class NewCaseVisualPanel1 extends JPanel implements DocumentListener{
// End of variables declaration//GEN-END:variables
/**
* Gives notification that there was an insert into the document. The
* range given by the DocumentEvent bounds the freshly inserted region.
* Gives notification that there was an insert into the document. The range
* given by the DocumentEvent bounds the freshly inserted region.
*
* @param e the document event
* @param e the document event
*/
@Override
public void insertUpdate(DocumentEvent e) {
@ -220,11 +220,11 @@ final class NewCaseVisualPanel1 extends JPanel implements DocumentListener{
}
/**
* Gives notification that a portion of the document has been
* removed. The range is given in terms of what the view last
* saw (that is, before updating sticky positions).
* Gives notification that a portion of the document has been removed. The
* range is given in terms of what the view last saw (that is, before
* updating sticky positions).
*
* @param e the document event
* @param e the document event
*/
@Override
public void removeUpdate(DocumentEvent e) {
@ -235,7 +235,7 @@ final class NewCaseVisualPanel1 extends JPanel implements DocumentListener{
/**
* Gives notification that an attribute or set of attributes changed.
*
* @param e the document event
* @param e the document event
*/
@Override
public void changedUpdate(DocumentEvent e) {
@ -245,20 +245,20 @@ final class NewCaseVisualPanel1 extends JPanel implements DocumentListener{
/**
* The "listener" that listens when the fields in this form are updated.
* This method is used to determine when to enable / disable the "Finish" button.
* This method is used to determine when to enable / disable the "Finish"
* button.
*
* @param e the document event
* @param e the document event
*/
public void updateUI(DocumentEvent e) {
String caseName = getCaseName();
String parentDir = getCaseParentDir();
if(!caseName.equals("") && !parentDir.equals("")){
caseDirTextField.setText( parentDir + caseName);
if (!caseName.equals("") && !parentDir.equals("")) {
caseDirTextField.setText(parentDir + caseName);
wizPanel.setIsFinish(true);
}
else{
} else {
caseDirTextField.setText("");
wizPanel.setIsFinish(false);
}

View File

@ -32,28 +32,30 @@ import java.awt.*;
*
* @author dfickling
*/
class NewCaseVisualPanel2 extends javax.swing.JPanel {
class NewCaseVisualPanel2 extends javax.swing.JPanel {
/** Creates new form NewCaseVisualPanel2 */
/**
* Creates new form NewCaseVisualPanel2
*/
public NewCaseVisualPanel2() {
initComponents();
}
/**
* Returns the name of the this panel. This name will be shown on the left
* panel of the "New Case" wizard panel.
*
* @return name the name of this panel
* @return name the name of this panel
*/
@Override
public String getName() {
return NbBundle.getMessage(this.getClass(), "NewCaseVisualPanel2.getName.text");
}
/** 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.
/**
* 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
@ -126,6 +128,4 @@ import java.awt.*;
return examinerTextField.getText();
}
}

View File

@ -16,7 +16,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
import java.awt.Component;
@ -38,10 +37,10 @@ import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Action to open the New Case wizard.
*/
final class NewCaseWizardAction extends CallableSystemAction {
final class NewCaseWizardAction extends CallableSystemAction {
private WizardDescriptor.Panel<WizardDescriptor>[] panels;
private static final Logger logger = Logger.getLogger(NewCaseWizardAction.class.getName());
@Override
@ -52,9 +51,9 @@ import org.sleuthkit.autopsy.coreutils.Logger;
String closeCurrentCase = NbBundle
.getMessage(this.getClass(), "NewCaseWizardAction.closeCurCase.confMsg.msg");
NotifyDescriptor d = new NotifyDescriptor.Confirmation(closeCurrentCase,
NbBundle.getMessage(this.getClass(),
"NewCaseWizardAction.closeCurCase.confMsg.title"),
NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
NbBundle.getMessage(this.getClass(),
"NewCaseWizardAction.closeCurCase.confMsg.title"),
NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
d.setValue(NotifyDescriptor.NO_OPTION);
Object res = DialogDisplayer.getDefault().notify(d);
@ -83,7 +82,6 @@ import org.sleuthkit.autopsy.coreutils.Logger;
dialog.setVisible(true);
dialog.toFront();
boolean finished = wizardDescriptor.getValue() == WizardDescriptor.FINISH_OPTION; // check if it finishes (it's not cancelled)
boolean isCancelled = wizardDescriptor.getValue() == WizardDescriptor.CANCEL_OPTION; // check if the "Cancel" button is pressed
@ -98,7 +96,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
// if Cancel button is pressed
if (isCancelled) {
String createdDirectory = (String) wizardDescriptor.getProperty("createdDirectory"); //NON-NLS
if(createdDirectory != null) {
if (createdDirectory != null) {
logger.log(Level.INFO, "Deleting a created case directory due to isCancelled set, dir: " + createdDirectory); //NON-NLS
Case.deleteCaseDirectory(new File(createdDirectory));
}
@ -113,16 +111,16 @@ import org.sleuthkit.autopsy.coreutils.Logger;
}
/**
* Initialize panels representing individual wizard's steps and sets
* various properties for them influencing wizard appearance.
* Initialize panels representing individual wizard's steps and sets various
* properties for them influencing wizard appearance.
*/
@SuppressWarnings({"unchecked", "rawtypes"})
private WizardDescriptor.Panel<WizardDescriptor>[] getPanels() {
if (panels == null) {
panels = new WizardDescriptor.Panel[]{
new NewCaseWizardPanel1(),
new NewCaseWizardPanel2()
};
new NewCaseWizardPanel1(),
new NewCaseWizardPanel2()
};
String[] steps = new String[panels.length];
for (int i = 0; i < panels.length; i++) {
Component c = panels[i].getComponent();

View File

@ -89,7 +89,7 @@ class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDesc
* button will be enabled.
*
* @return boolean true if all the fields are correctly filled, false
* otherwise
* otherwise
*/
@Override
public boolean isValid() {
@ -226,11 +226,11 @@ class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDesc
// get confirmation to create directory
String confMsg = NbBundle
.getMessage(this.getClass(), "NewCaseWizardPanel1.validate.confMsg.createDir.msg",
caseParentDir);
caseParentDir);
NotifyDescriptor d2 = new NotifyDescriptor.Confirmation(confMsg,
NbBundle.getMessage(this.getClass(),
"NewCaseWizardPanel1.validate.confMsg.createDir.title"),
NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
NbBundle.getMessage(this.getClass(),
"NewCaseWizardPanel1.validate.confMsg.createDir.title"),
NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE);
d2.setValue(NotifyDescriptor.NO_OPTION);
Object res2 = DialogDisplayer.getDefault().notify(d2);
@ -240,8 +240,8 @@ class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDesc
createDirectory(caseDirPath);
} catch (Exception ex) {
String errorMsg = NbBundle.getMessage(this.getClass(),
"NewCaseWizardPanel1.validate.errMsg.cantCreateParDir.msg",
caseParentDir);
"NewCaseWizardPanel1.validate.errMsg.cantCreateParDir.msg",
caseParentDir);
logger.log(Level.WARNING, errorMsg, ex);
validationError(errorMsg);
}
@ -249,8 +249,8 @@ class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDesc
if (res2 != null && res2 == DialogDescriptor.NO_OPTION) {
// if user say no
validationError(NbBundle.getMessage(this.getClass(),
"NewCaseWizardPanel1.validate.errMsg.prevCreateBaseDir.msg",
caseDirPath) );
"NewCaseWizardPanel1.validate.errMsg.prevCreateBaseDir.msg",
caseDirPath));
}
} else {
try {
@ -298,10 +298,10 @@ class NewCaseWizardPanel1 implements WizardDescriptor.ValidatingPanel<WizardDesc
}
String errorMsg = NbBundle.getMessage(this.getClass(),
"NewCaseWizardPanel1.createDir.errMsg.cantCreateDir.msg");
"NewCaseWizardPanel1.createDir.errMsg.cantCreateDir.msg");
validationError(errorMsg);
} // the new case directory is successfully created
else {
createdDirectory = caseDirPath;

View File

@ -16,7 +16,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
import java.util.HashSet;
@ -32,9 +31,9 @@ import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
/**
* The "New Case" wizard panel with a component on it. This class represents
* data of wizard step. It defers creation and initialization of UI component
* of wizard panel into getComponent() method.
* The "New Case" wizard panel with a component on it. This class represents
* data of wizard step. It defers creation and initialization of UI component of
* wizard panel into getComponent() method.
*
* @author jantonius
*/
@ -56,7 +55,7 @@ class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel<WizardDesc
* but never displayed, or not all panels are displayed, it is better to
* create only those which really need to be visible.
*
* @return component the UI component of this wizard panel
* @return component the UI component of this wizard panel
*/
@Override
public NewCaseVisualPanel2 getComponent() {
@ -69,8 +68,8 @@ class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel<WizardDesc
/**
* Help for this panel. When the panel is active, this is used as the help
* for the wizard dialog.
*
* @return HelpCtx.DEFAULT_HELP the help for this panel
*
* @return HelpCtx.DEFAULT_HELP the help for this panel
*/
@Override
public HelpCtx getHelp() {
@ -84,7 +83,8 @@ class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel<WizardDesc
* Tests whether the panel is finished. If the panel is valid, the "Finish"
* button will be enabled.
*
* @return boolean true if all the fields are correctly filled, false otherwise
* @return boolean true if all the fields are correctly filled, false
* otherwise
*/
@Override
public boolean isValid() {
@ -101,7 +101,7 @@ class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel<WizardDesc
/**
* Adds a listener to changes of the panel's validity.
*
* @param l the change listener to add
* @param l the change listener to add
*/
@Override
public final void addChangeListener(ChangeListener l) {
@ -113,7 +113,7 @@ class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel<WizardDesc
/**
* Removes a listener to changes of the panel's validity.
*
* @param l the change listener to move
* @param l the change listener to move
*/
@Override
public final void removeChangeListener(ChangeListener l) {
@ -123,8 +123,8 @@ class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel<WizardDesc
}
/**
* This method is auto-generated. It seems that this method is used to listen
* to any change in this wizard panel.
* This method is auto-generated. It seems that this method is used to
* listen to any change in this wizard panel.
*/
protected final void fireChangeEvent() {
Iterator<ChangeListener> it;
@ -146,8 +146,8 @@ class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel<WizardDesc
* or already-modified settings, if the user used the previous and/or next
* buttons. This method can be called multiple times on one instance of
* WizardDescriptor.Panel.
*
* @param settings the setting to be read from
*
* @param settings the setting to be read from
*/
@Override
public void readSettings(WizardDescriptor settings) {
@ -157,13 +157,13 @@ class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel<WizardDesc
}
/**
* Provides the wizard panel with the opportunity to update the settings
* with its current customized state. Rather than updating its settings
* with every change in the GUI, it should collect them, and then only save
* them when requested to by this method. This method can be called multiple
* Provides the wizard panel with the opportunity to update the settings
* with its current customized state. Rather than updating its settings with
* every change in the GUI, it should collect them, and then only save them
* when requested to by this method. This method can be called multiple
* times on one instance of WizardDescriptor.Panel.
*
* @param settings the setting to be stored to
* @param settings the setting to be stored to
*/
@Override
public void storeSettings(WizardDescriptor settings) {
@ -171,12 +171,12 @@ class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel<WizardDesc
@Override
public void validate() throws WizardValidationException {
NewCaseVisualPanel2 currentComponent = getComponent();
final String caseNumber = currentComponent.getCaseNumber();
final String examiner = currentComponent.getExaminer();
try {
SwingUtilities.invokeLater(new Runnable(){
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
@ -186,15 +186,15 @@ class NewCaseWizardPanel2 implements WizardDescriptor.ValidatingPanel<WizardDesc
Exceptions.printStackTrace(ex);
}
}
});
});
//Case.create(createdDirectory, caseName, caseNumber, examiner);
} catch(Exception ex) {
} catch (Exception ex) {
throw new WizardValidationException(this.getComponent(),
NbBundle.getMessage(this.getClass(),
"NewCaseWizardPanel2.validate.errCreateCase.msg"),
null);
NbBundle.getMessage(this.getClass(),
"NewCaseWizardPanel2.validate.errCreateCase.msg"),
null);
}
}
}

View File

@ -28,12 +28,15 @@ import org.netbeans.spi.sendopts.OptionProcessor;
import org.openide.util.lookup.ServiceProvider;
/**
* Allows Autopsy to get path to .aut file passed in via associating the file type in Windows.
* Allows Autopsy to get path to .aut file passed in via associating the file
* type in Windows.
*/
@ServiceProvider(service = OptionProcessor.class)
public class OpenFromArguments extends OptionProcessor {
/* Stores the .aut file if it was passed in as argument */
/*
* Stores the .aut file if it was passed in as argument
*/
private String autPath = "";
private final Option option1 = Option.defaultArguments();

View File

@ -201,19 +201,19 @@ class OpenRecentCasePanel extends javax.swing.JPanel {
try {
if (caseName.equals("") || casePath.equals("") || (!new File(casePath).exists())) {
JOptionPane.showMessageDialog(null,
NbBundle.getMessage(this.getClass(),
"OpenRecentCasePanel.openCase.msgDlg.caseDoesntExist.msg",
caseName),
NbBundle.getMessage(this.getClass(),
"OpenRecentCasePanel.openCase.msgDlg.err"),
JOptionPane.ERROR_MESSAGE);
NbBundle.getMessage(this.getClass(),
"OpenRecentCasePanel.openCase.msgDlg.caseDoesntExist.msg",
caseName),
NbBundle.getMessage(this.getClass(),
"OpenRecentCasePanel.openCase.msgDlg.err"),
JOptionPane.ERROR_MESSAGE);
RecentCases.getInstance().removeRecentCase(caseName, casePath); // remove the recent case if it doesn't exist anymore
//if case is not opened, open the start window
//if case is not opened, open the start window
if (Case.isCaseOpen() == false) {
StartupWindowProvider.getInstance().open();
}
} else {
Case.open(casePath); // open the case
}

View File

@ -16,7 +16,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
import java.awt.event.ActionEvent;
@ -39,11 +38,11 @@ import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* The action in this class is to clear the list of "Recent Cases".
* The constructor is called when the autopsy is running.
* All the method to create and modify the properties file are within this class
* The action in this class is to clear the list of "Recent Cases". The
* constructor is called when the autopsy is running. All the method to create
* and modify the properties file are within this class
*/
final class RecentCases extends CallableSystemAction implements Presenter.Menu {
final class RecentCases extends CallableSystemAction implements Presenter.Menu {
static final int LENGTH = 5;
static final String NAME_PROP_KEY = "LBL_RecentCase_Name"; //NON-NLS
@ -54,33 +53,35 @@ import org.sleuthkit.autopsy.coreutils.Logger;
private Deque<RecentCase> recentCases; // newest case is last case
/**
* Gets the instance of the RecentCases singleton.
*
*
* @return INSTANCE the RecentCases singleton
*
* @return INSTANCE the RecentCases singleton
*/
static public RecentCases getInstance() {
INSTANCE.refreshRecentCases();
return INSTANCE;
}
/** the constructor */
/**
* the constructor
*/
private RecentCases() {
for (int i = 0; i < LENGTH; i++) {
try{
if(ModuleSettings.getConfigSetting(ModuleSettings.MAIN_SETTINGS, nameKey(i)) == null)
ModuleSettings.setConfigSetting(ModuleSettings.MAIN_SETTINGS, nameKey(i), "");
if(ModuleSettings.getConfigSetting(ModuleSettings.MAIN_SETTINGS, pathKey(i)) == null)
ModuleSettings.setConfigSetting(ModuleSettings.MAIN_SETTINGS, pathKey(i), "");
}
catch(Exception e ){
try {
if (ModuleSettings.getConfigSetting(ModuleSettings.MAIN_SETTINGS, nameKey(i)) == null) {
ModuleSettings.setConfigSetting(ModuleSettings.MAIN_SETTINGS, nameKey(i), "");
}
if (ModuleSettings.getConfigSetting(ModuleSettings.MAIN_SETTINGS, pathKey(i)) == null) {
ModuleSettings.setConfigSetting(ModuleSettings.MAIN_SETTINGS, pathKey(i), "");
}
} catch (Exception e) {
}
}
// Load recentCases from properties
recentCases = new LinkedList<RecentCase>();
@ -90,7 +91,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
recentCases.add(rc);
}
}
refreshRecentCases();
}
@ -112,19 +113,17 @@ import org.sleuthkit.autopsy.coreutils.Logger;
}
private String getName(int i) {
try{
return ModuleSettings.getConfigSetting(ModuleSettings.MAIN_SETTINGS, nameKey(i));
}
catch(Exception e){
try {
return ModuleSettings.getConfigSetting(ModuleSettings.MAIN_SETTINGS, nameKey(i));
} catch (Exception e) {
return null;
}
}
private String getPath(int i) {
try{
return ModuleSettings.getConfigSetting(ModuleSettings.MAIN_SETTINGS, pathKey(i));
}
catch(Exception e){
try {
return ModuleSettings.getConfigSetting(ModuleSettings.MAIN_SETTINGS, pathKey(i));
} catch (Exception e) {
return null;
}
}
@ -145,29 +144,33 @@ import org.sleuthkit.autopsy.coreutils.Logger;
private static final class RecentCase {
String name, path;
/**
* @param name The case name or "" if a blank placeholder case
* @param path A normalized path (via FileUtil.normalizePath(path)) or "" if a blank placeholder case
* @param path A normalized path (via FileUtil.normalizePath(path)) or
* "" if a blank placeholder case
*/
private RecentCase(String name, String path) {
this.name = name;
this.path = path;
}
/**
* Used when creating RecentCases with external data. The path must be
* Used when creating RecentCases with external data. The path must be
* normalized so that duplicate cases always have the same path.
* @param name The case name.
*
* @param name The case name.
* @param unsafePath The (potentially un-normalized) case path.
*
* @return The created RecentCase.s
*/
static RecentCase createSafe(String name, String unsafePath) {
return new RecentCase(name, FileUtil.normalizePath(unsafePath));
}
/**
* Does this case exist or was it manually deleted or moved?
*
* @return true if the case exists, false otherwise
*/
boolean exists() {
@ -201,15 +204,15 @@ import org.sleuthkit.autopsy.coreutils.Logger;
return true;
}
}
/**
* Refresh the current list of cases, removing any cases that
* no longer exist.
* Refresh the current list of cases, removing any cases that no longer
* exist.
*/
private void refreshRecentCases() {
List<RecentCase> toDelete = new ArrayList<RecentCase>();
for (RecentCase rc : recentCases) {
if(!rc.exists()) {
if (!rc.exists()) {
toDelete.add(rc);
}
}
@ -238,7 +241,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Gets a menu item that can present this action in a JMenu.
*
* @return menuItem the representation menu item for this action
* @return menuItem the representation menu item for this action
*/
@Override
public JMenuItem getMenuPresenter() {
@ -248,7 +251,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
/**
* This action is used to clear all the recent cases menu options.
*
* @param e the action event
* @param e the action event
*/
@Override
public void actionPerformed(ActionEvent e) {
@ -267,20 +270,22 @@ import org.sleuthkit.autopsy.coreutils.Logger;
private void addRecentCase(RecentCase rc) {
// remove the case if it's already in the list
recentCases.remove(rc);
// make space if it's needed
if (recentCases.size() == LENGTH) recentCases.remove();
if (recentCases.size() == LENGTH) {
recentCases.remove();
}
recentCases.add(rc);
}
/**
* Adds a recent case to the top of the list. If the case is already in the
* list, it will be removed before the new entry is added.
* list, it will be removed before the new entry is added.
*
* @param name the name of the recent case to be added
* @param unsafePath the (potentially un-normalized) path of the case
* config file
* @param name the name of the recent case to be added
* @param unsafePath the (potentially un-normalized) path of the case config
* file
*/
public void addRecentCase(String name, String unsafePath) {
RecentCase rc = RecentCase.createSafe(name, unsafePath);
@ -299,10 +304,11 @@ import org.sleuthkit.autopsy.coreutils.Logger;
/**
* This method is used to update the name and path of a RecentCase.
*
* @param oldName the old recent case name
* @param oldPath the old recent case config file path
* @param newName the new recent case name
* @param newPath the new recent case config file path
* @param oldName the old recent case name
* @param oldPath the old recent case config file path
* @param newName the new recent case name
* @param newPath the new recent case config file path
*
* @throws Exception
*/
public void updateRecentCase(String oldName, String oldPath, String newName, String newPath) throws Exception {
@ -326,17 +332,18 @@ import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Gets the total number of recent cases
*
* @return total total number of recent cases
* @return total total number of recent cases
*/
public int getTotalRecentCases() {
return recentCases.size();
}
/**
* This method is used to remove the selected name and path of the RecentCase
* This method is used to remove the selected name and path of the
* RecentCase
*
* @param name the case name to be removed from the recent case
* @param path the config file path to be removed from the recent case
* @param name the case name to be removed from the recent case
* @param path the config file path to be removed from the recent case
*/
public void removeRecentCase(String name, String path) {
RecentCase rc = RecentCase.createSafe(name, path);
@ -344,7 +351,6 @@ import org.sleuthkit.autopsy.coreutils.Logger;
// remove all instances of the old recent case
recentCases.removeAll(Arrays.asList(rc));
this.getMenuPresenter().setVisible(true); // invoke the contructor again
// write the properties file
@ -359,7 +365,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
* Gets the recent case names.
*
* @return caseNames An array String[LENGTH], newest case first, with any
* extra spots filled with ""
* extra spots filled with ""
*/
public String[] getRecentCaseNames() {
String[] caseNames = new String[LENGTH];
@ -383,7 +389,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
* Gets the recent case paths.
*
* @return casePaths An array String[LENGTH], newest case first, with any
* extra spots filled with ""
* extra spots filled with ""
*/
public String[] getRecentCasePaths() {
String[] casePaths = new String[LENGTH];

View File

@ -16,7 +16,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
import java.awt.EventQueue;
@ -39,8 +38,10 @@ class RecentItems implements ActionListener {
String casePath;
private JPanel caller; // for error handling
/** the constructor */
public RecentItems(String caseName, String casePath){
/**
* the constructor
*/
public RecentItems(String caseName, String casePath) {
this.caseName = caseName;
this.casePath = casePath;
}
@ -48,20 +49,20 @@ class RecentItems implements ActionListener {
/**
* Opens the recent case.
*
* @param e the action event
* @param e the action event
*/
@Override
public void actionPerformed(ActionEvent e) {
// check if the file exists
if(caseName.equals("") || casePath.equals("") || (!new File(casePath).exists())){
if (caseName.equals("") || casePath.equals("") || (!new File(casePath).exists())) {
// throw an error here
JOptionPane.showMessageDialog(caller,
NbBundle.getMessage(this.getClass(), "RecentItems.openRecentCase.msgDlg.text",
caseName),
NbBundle.getMessage(this.getClass(), "RecentItems.openRecentCase.msgDlg.err"),
JOptionPane.ERROR_MESSAGE);
NbBundle.getMessage(this.getClass(), "RecentItems.openRecentCase.msgDlg.text",
caseName),
NbBundle.getMessage(this.getClass(), "RecentItems.openRecentCase.msgDlg.err"),
JOptionPane.ERROR_MESSAGE);
RecentCases.getInstance().removeRecentCase(caseName, casePath); // remove the recent case if it doesn't exist anymore
//if case is not opened, open the start window
if (Case.isCaseOpen() == false) {
EventQueue.invokeLater(new Runnable() {
@ -70,12 +71,11 @@ class RecentItems implements ActionListener {
public void run() {
StartupWindowProvider.getInstance().open();
}
});
}
}
else {
} else {
try {
Case.open(casePath); // open the case
} catch (CaseActionException ex) {

View File

@ -16,8 +16,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
import java.awt.Dimension;
@ -34,7 +32,7 @@ import org.openide.windows.WindowManager;
/**
* The default implementation of the Autopsy startup window
*/
@ServiceProvider(service=StartupWindowInterface.class)
@ServiceProvider(service = StartupWindowInterface.class)
public final class StartupWindow extends JDialog implements StartupWindowInterface {
private static StartupWindow instance;
@ -47,7 +45,6 @@ public final class StartupWindow extends JDialog implements StartupWindowInterfa
init();
}
/**
* Shows the startup window.
*/
@ -62,7 +59,7 @@ public final class StartupWindow extends JDialog implements StartupWindowInterfa
// set the location of the popUp Window on the center of the screen
setLocation((screenDimension.width - w) / 2, (screenDimension.height - h) / 2);
welcomeWindow = new CueBannerPanel();
// add the command to close the window to the button on the Volume Detail Panel
@ -79,7 +76,7 @@ public final class StartupWindow extends JDialog implements StartupWindowInterfa
setResizable(false);
}
@Override
public void open() {
welcomeWindow.refresh();

View File

@ -27,10 +27,11 @@ import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Provides the start up window to rest of the application. It may return the
* main / default startup window, or a custom one if it has been discovered.
*
* All that is required to create a custom startup window in a module and active it,
* is to implement StartupWindowInterface and register it with lookup as a ServiceProvider.
* The custom startup window is automatically chosen over the default one, given it is the only external module custom startup window.
*
* All that is required to create a custom startup window in a module and active
* it, is to implement StartupWindowInterface and register it with lookup as a
* ServiceProvider. The custom startup window is automatically chosen over the
* default one, given it is the only external module custom startup window.
*/
public class StartupWindowProvider implements StartupWindowInterface {
@ -54,8 +55,8 @@ public class StartupWindowProvider implements StartupWindowInterface {
private void init() {
if (startupWindowToUse == null) {
//discover the registered windows
Collection<? extends StartupWindowInterface> startupWindows =
Lookup.getDefault().lookupAll(StartupWindowInterface.class);
Collection<? extends StartupWindowInterface> startupWindows
= Lookup.getDefault().lookupAll(StartupWindowInterface.class);
int windowsCount = startupWindows.size();
if (windowsCount > 2) {
@ -75,14 +76,13 @@ public class StartupWindowProvider implements StartupWindowInterface {
}
}
if (startupWindowToUse == null) {
logger.log(Level.SEVERE, "Unexpected error, no custom startup window found, using the default"); //NON-NLS
startupWindowToUse = new org.sleuthkit.autopsy.casemodule.StartupWindow();
}
}
}
}
}
@ -96,8 +96,8 @@ public class StartupWindowProvider implements StartupWindowInterface {
@Override
public void close() {
if (startupWindowToUse != null) {
startupWindowToUse.close();
}
if (startupWindowToUse != null) {
startupWindowToUse.close();
}
}
}

View File

@ -16,7 +16,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.casemodule;
import javax.swing.JComponent;
@ -29,13 +28,15 @@ import org.openide.util.actions.SystemAction;
/**
* This class is used to change / update the list of recent cases dynamically.
*/
class UpdateRecentCases extends JMenuItem implements DynamicMenuContent {
class UpdateRecentCases extends JMenuItem implements DynamicMenuContent {
int length;
static boolean hasRecentCase = false;
/** the constructor */
UpdateRecentCases(){
/**
* the constructor
*/
UpdateRecentCases() {
length = RecentCases.LENGTH;
}
@ -55,7 +56,7 @@ import org.openide.util.actions.SystemAction;
// if it has the recent menus, add them to the component list
for (int i = 0; i < length; i++) {
if((!caseName[i].equals(""))){
if ((!caseName[i].equals(""))) {
JMenuItem menuItem = new JMenuItem(caseName[i]);
menuItem.setActionCommand(caseName[i].toUpperCase());
menuItem.addActionListener(new RecentItems(caseName[i], casePath[i]));
@ -65,15 +66,14 @@ import org.openide.util.actions.SystemAction;
}
// if it has recent case, create clear menu
if(hasRecentCase){
if (hasRecentCase) {
comps[length] = new JSeparator();
JMenuItem clearMenu = new JMenuItem(
NbBundle.getMessage(this.getClass(), "UpdateRecentCases.menuItem.clearRecentCases.text"));
clearMenu.addActionListener(SystemAction.get(RecentCases.class));
comps[length+1] = clearMenu;
}
// otherwise, just create a disabled empty menu
else{
comps[length + 1] = clearMenu;
} // otherwise, just create a disabled empty menu
else {
comps = new JComponent[1];
JMenuItem emptyMenu = new JMenuItem(NbBundle.getMessage(this.getClass(), "UpdateRecentCases.menuItem.empty"));
emptyMenu.addActionListener(new RecentItems("", ""));
@ -84,13 +84,17 @@ import org.openide.util.actions.SystemAction;
}
/**
* Updates main menu presenters. This method is called only by the main menu processing.
* Updates main menu presenters. This method is called only by the main menu
* processing.
*
* @param jcs the previously used menu items returned by previous call to getMenuPresenters() or synchMenuPresenters()
* @return menu a new set of items to show in menu. Can be either an updated old set of instances or a completely new one.
* @param jcs the previously used menu items returned by previous call to
* getMenuPresenters() or synchMenuPresenters()
*
* @return menu a new set of items to show in menu. Can be either an updated
* old set of instances or a completely new one.
*/
@Override
public JComponent[] synchMenuPresenters(JComponent[] jcs) {
return getMenuPresenters();
}
}
}

View File

@ -46,7 +46,7 @@ import org.xml.sax.SAXException;
*
* @author jantonius
*/
class XMLCaseManagement implements CaseConfigFileInterface {
class XMLCaseManagement implements CaseConfigFileInterface {
final static String XSDFILE = "CaseSchema.xsd"; //NON-NLS
final static String TOP_ROOT_NAME = "AutopsyCase"; //NON-NLS
@ -323,7 +323,7 @@ import org.xml.sax.SAXException;
* Gets the Autopsy Saved Version from the document handler
*
* @return savedVersion the latest version of autopsy when this case is
* saved
* saved
*/
protected String getSavedVersion() {
if (doc != null) {
@ -437,10 +437,10 @@ import org.xml.sax.SAXException;
* Initialize the basic values for a new case management file. Note: this is
* the schema version 1.0
*
* @param dirPath case directory path
* @param caseName the name of the config file to be located in the case
* directory
* @param examiner examiner for the case (optional, can be empty string
* @param dirPath case directory path
* @param caseName the name of the config file to be located in the case
* directory
* @param examiner examiner for the case (optional, can be empty string
* @param caseNumber case number (optional), can be empty
*/
protected void create(String dirPath, String caseName, String examiner, String caseNumber) throws CaseActionException {
@ -596,7 +596,6 @@ import org.xml.sax.SAXException;
clear();
File file = new File(conFilePath);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = null;
try {
@ -605,18 +604,17 @@ import org.xml.sax.SAXException;
} catch (ParserConfigurationException ex) {
throw new CaseActionException(
NbBundle.getMessage(this.getClass(), "XMLCaseManagement.open.exception.errReadXMLFile.msg",
conFilePath), ex);
conFilePath), ex);
} catch (SAXException ex) {
throw new CaseActionException(
NbBundle.getMessage(this.getClass(), "XMLCaseManagement.open.exception.errReadXMLFile.msg",
conFilePath), ex);
conFilePath), ex);
} catch (IOException ex) {
throw new CaseActionException(
NbBundle.getMessage(this.getClass(), "XMLCaseManagement.open.exception.errReadXMLFile.msg",
conFilePath), ex);
conFilePath), ex);
}
doc.getDocumentElement().normalize();
doc.getDocumentElement().normalize();
@ -632,14 +630,16 @@ import org.xml.sax.SAXException;
// throw an error ...
clear();
JOptionPane.showMessageDialog(caller,
NbBundle.getMessage(this.getClass(),
"XMLCaseManagement.open.msgDlg.notAutCase.msg",
file.getName(), className),
NbBundle.getMessage(this.getClass(),
"XMLCaseManagement.open.msgDlg.notAutCase.title"),
JOptionPane.ERROR_MESSAGE);
NbBundle.getMessage(this.getClass(),
"XMLCaseManagement.open.msgDlg.notAutCase.msg",
file.getName(), className),
NbBundle.getMessage(this.getClass(),
"XMLCaseManagement.open.msgDlg.notAutCase.title"),
JOptionPane.ERROR_MESSAGE);
} else {
/* Autopsy Created Version */
/*
* Autopsy Created Version
*/
String createdVersion = getCreatedVersion(); // get the created version
// check if it has the same autopsy version as the current one
@ -648,7 +648,9 @@ import org.xml.sax.SAXException;
getRootElement().getElementsByTagName(AUTOPSY_MVERSION_NAME).item(0).setTextContent(autopsySavedVersion);
}
/* Schema Version */
/*
* Schema Version
*/
String schemaVer = getSchemaVersion();
// check if it has the same schema version as the current one
if (!schemaVer.equals(schemaVersion)) {
@ -664,24 +666,21 @@ import org.xml.sax.SAXException;
}
}
/**
* When user wants to close the case. This method writes any changes to the
* XML case configuration file, closes it and the document handler, and
* clears all the local variables / fields.
*
*/
@Override
public void close() throws CaseActionException {
writeFile(); // write any changes to xml
clear();
}
/**
* When user wants to close the case. This method writes any changes to
* the XML case configuration file, closes it and the document handler,
* and clears all the local variables / fields.
*
*/
@Override
public void close() throws CaseActionException {
writeFile(); // write any changes to xml
clear();
}
/**
* Clear the internal structures / variables
*/
/**
* Clear the internal structures / variables
*/
private void clear() {
doc = null;
caseDirPath = "";

View File

@ -76,7 +76,6 @@ public class FileManager implements Closeable {
logger.log(Level.SEVERE, "Error initializing FileManager and getting number of local file sets"); //NON-NLS
}
}
/**
@ -198,7 +197,8 @@ public class FileManager implements Closeable {
}
/**
* Adds a carved file to the VirtualDirectory '$CarvedFiles' in the volume or image given by systemId.
* Adds a carved file to the VirtualDirectory '$CarvedFiles' in the volume
* or image given by systemId.
*
* @param carvedFileName the name of the carved file (containing appropriate
* extension)
@ -221,24 +221,28 @@ public class FileManager implements Closeable {
}
/**
* Adds a collection of carved files to the VirtualDirectory '$CarvedFiles' in the volume or image given by
* systemId. Creates $CarvedFiles if it does not exist already.
* Adds a collection of carved files to the VirtualDirectory '$CarvedFiles'
* in the volume or image given by systemId. Creates $CarvedFiles if it does
* not exist already.
*
* @param filesToAdd a list of CarvedFileContainer files to add as carved
* files
*
* @return List<LayoutFile> This is a list of the files added to the
* database
*
* @param filesToAdd a list of CarvedFileContainer files to add as carved files
* @return List<LayoutFile> This is a list of the files added to the database
* @throws org.sleuthkit.datamodel.TskCoreException
*/
public List<LayoutFile> addCarvedFiles(List<CarvedFileContainer> filesToAdd) throws TskCoreException {
if (tskCase == null) {
throw new TskCoreException(NbBundle.getMessage(this.getClass(), "FileManager.addCarvedFile.exception.msg"));
}
else {
return tskCase.addCarvedFiles(filesToAdd);
}
if (tskCase == null) {
throw new TskCoreException(NbBundle.getMessage(this.getClass(), "FileManager.addCarvedFile.exception.msg"));
} else {
return tskCase.addCarvedFiles(filesToAdd);
}
}
/**
*
*
* Interface for receiving notifications on folders being added via a
* callback
*/
@ -277,7 +281,7 @@ public class FileManager implements Closeable {
if (!localFile.exists() || !localFile.canRead()) {
String msg = NbBundle
.getMessage(this.getClass(), "FileManager.addLocalFilesDirs.exception.notReadable.msg",
localFile.getAbsolutePath());
localFile.getAbsolutePath());
logger.log(Level.SEVERE, msg);
throw new TskCoreException(msg);
}
@ -296,7 +300,7 @@ public class FileManager implements Closeable {
if (localFileAdded == null) {
String msg = NbBundle
.getMessage(this.getClass(), "FileManager.addLocalFilesDirs.exception.cantAdd.msg",
localRootToAdd.getAbsolutePath());
localRootToAdd.getAbsolutePath());
logger.log(Level.SEVERE, msg);
throw new TskCoreException(msg);
} else {
@ -337,7 +341,7 @@ public class FileManager implements Closeable {
} catch (TskCoreException ex) {
String msg = NbBundle
.getMessage(this.getClass(), "FileManager.addLocalFileSetRootDir.exception.errCreateDir.msg",
fileSetName);
fileSetName);
logger.log(Level.SEVERE, msg, ex);
throw new TskCoreException(msg, ex);
}
@ -370,15 +374,14 @@ public class FileManager implements Closeable {
if (!localFile.exists()) {
throw new TskCoreException(
NbBundle.getMessage(this.getClass(), "FileManager.addLocalDirInt.exception.doesntExist.msg",
localFile.getAbsolutePath()));
localFile.getAbsolutePath()));
}
if (!localFile.canRead()) {
throw new TskCoreException(
NbBundle.getMessage(this.getClass(), "FileManager.addLocalDirInt.exception.notReadable.msg",
localFile.getAbsolutePath()));
localFile.getAbsolutePath()));
}
if (localFile.isDirectory()) {
//create virtual folder (we don't have a notion of a 'local folder')
final VirtualDirectory childVd = tskCase.addVirtualDirectory(parentVd.getId(), localFile.getName(), trans);

View File

@ -34,8 +34,8 @@ import org.sleuthkit.datamodel.SleuthkitCase;
* A class to manage various services.
*/
public class Services implements Closeable {
private final List<Closeable> services = new ArrayList<>();
private final List<Closeable> services = new ArrayList<>();
private final FileManager fileManager;
private final TagsManager tagsManager;
private final KeywordSearchService keywordSearchService;
@ -43,18 +43,18 @@ public class Services implements Closeable {
public Services(SleuthkitCase tskCase) {
fileManager = new FileManager(tskCase);
services.add(fileManager);
tagsManager = new TagsManager(tskCase);
services.add(tagsManager);
keywordSearchService = Lookup.getDefault().lookup(KeywordSearchService.class);
services.add(keywordSearchService);
}
public FileManager getFileManager() {
return fileManager;
}
public TagsManager getTagsManager() {
return tagsManager;
}
@ -62,12 +62,12 @@ public class Services implements Closeable {
public KeywordSearchService getKeywordSearchService() {
return keywordSearchService;
}
@Override
public void close() throws IOException {
for (Closeable service : services) {
service.close();
}
}
}

View File

@ -16,7 +16,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.contentviewers;
import java.awt.Component;
@ -31,13 +30,13 @@ import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData.TSK_DB_FILES_TYPE_ENUM;
/**
* Shows file metadata as a list to make it easy to copy and paste.
* Typically shows the same data that can also be found in the ResultViewer table,
* just a different order and allows the full path to be visible in the bottom area.
* Shows file metadata as a list to make it easy to copy and paste. Typically
* shows the same data that can also be found in the ResultViewer table, just a
* different order and allows the full path to be visible in the bottom area.
*/
@ServiceProvider(service = DataContentViewer.class, position = 3)
public class Metadata extends javax.swing.JPanel implements DataContentViewer
{
public class Metadata extends javax.swing.JPanel implements DataContentViewer {
/**
* Creates new form Metadata
*/
@ -79,38 +78,32 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer
private javax.swing.JTextPane jTextPane1;
// End of variables declaration//GEN-END:variables
private void customizeComponents(){
private void customizeComponents() {
/*
jTextPane1.setComponentPopupMenu(rightClickMenu);
ActionListener actList = new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
JMenuItem jmi = (JMenuItem) e.getSource();
if(jmi.equals(copyMenuItem))
outputViewPane.copy();
else if(jmi.equals(selectAllMenuItem))
outputViewPane.selectAll();
}
};
copyMenuItem.addActionListener(actList);
selectAllMenuItem.addActionListener(actList);
*/
* jTextPane1.setComponentPopupMenu(rightClickMenu); ActionListener
* actList = new ActionListener(){ @Override public void
* actionPerformed(ActionEvent e){ JMenuItem jmi = (JMenuItem)
* e.getSource(); if(jmi.equals(copyMenuItem)) outputViewPane.copy();
* else if(jmi.equals(selectAllMenuItem)) outputViewPane.selectAll(); }
* }; copyMenuItem.addActionListener(actList);
* selectAllMenuItem.addActionListener(actList);
*/
Utilities.configureTextPaneAsHtml(jTextPane1);
}
private void setText(String str) {
jTextPane1.setText("<html><body>" + str + "</body></html>"); //NON-NLS
}
private void startTable(StringBuilder sb) {
sb.append("<table>"); //NON-NLS
}
private void endTable(StringBuilder sb) {
sb.append("</table>"); //NON-NLS
}
private void addRow(StringBuilder sb, String key, String value) {
sb.append("<tr><td>"); //NON-NLS
sb.append(key);
@ -118,7 +111,7 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer
sb.append(value);
sb.append("</td></tr>"); //NON-NLS
}
@Override
public void setNode(Node node) {
AbstractFile file = node.getLookup().lookup(AbstractFile.class);
@ -126,40 +119,43 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer
setText(NbBundle.getMessage(this.getClass(), "Metadata.nodeText.nonFilePassedIn"));
return;
}
StringBuilder sb = new StringBuilder();
startTable(sb);
try {
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.name"), file.getUniquePath());
} catch (TskCoreException ex) {
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.name"), file.getParentPath() + "/" + file.getName());
}
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.type"), file.getType().getName());
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.size"), new Long(file.getSize()).toString() );
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.size"), new Long(file.getSize()).toString());
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.fileNameAlloc"), file.getDirFlagAsString());
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.metadataAlloc"), file.getMetaFlagsAsString());
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.modified"), ContentUtils.getStringTime(file.getMtime(), file));
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.accessed"), ContentUtils.getStringTime(file.getAtime(), file));
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.created"), ContentUtils.getStringTime(file.getCrtime(), file));
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.changed"), ContentUtils.getStringTime(file.getCtime(), file));
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.created"), ContentUtils.getStringTime(file.getCrtime(), file));
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.changed"), ContentUtils.getStringTime(file.getCtime(), file));
String md5 = file.getMd5Hash();
if (md5 == null) {
md5 = NbBundle.getMessage(this.getClass(), "Metadata.tableRowContent.md5notCalc");
}
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.md5"), md5);
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.hashLookupResults"), file.getKnown().toString());
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.internalid"), new Long(file.getId()).toString());
if (file.getType().compareTo(TSK_DB_FILES_TYPE_ENUM.LOCAL) == 0) {
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.localPath"), file.getLocalAbsPath());
}
endTable(sb);
/* If we have a file system file, grab the more detailed metadata text too */
/*
* If we have a file system file, grab the more detailed metadata text
* too
*/
try {
if (file instanceof FsContent) {
FsContent fsFile = (FsContent) file;
@ -175,10 +171,10 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer
} catch (TskCoreException ex) {
sb.append(NbBundle.getMessage(this.getClass(), "Metadata.nodeText.exceptionNotice.text")).append(ex.getLocalizedMessage());
}
setText(sb.toString());
jTextPane1.setCaretPosition(0);
this.setCursor(null);
this.setCursor(null);
}
@Override

View File

@ -45,18 +45,19 @@ public class Installer extends ModuleInstall {
static {
loadDynLibraries();
}
private static void loadDynLibraries() {
/* On Windows, we distribute dlls that libtsk_jni depend on.
* If libtsk_jni tries to load them, they will not be found by
* Windows because they are in special NetBeans folders. So, we
* manually load them from within Autopsy so that they are found
* via the NetBeans loading setup. These are copied by the build
* script when making the ZIP file. In a development environment
* they will need to be loaded from standard places in your system.
*
/*
* On Windows, we distribute dlls that libtsk_jni depend on. If
* libtsk_jni tries to load them, they will not be found by Windows
* because they are in special NetBeans folders. So, we manually load
* them from within Autopsy so that they are found via the NetBeans
* loading setup. These are copied by the build script when making the
* ZIP file. In a development environment they will need to be loaded
* from standard places in your system.
*
* On non-Windows platforms, we assume the dependncies are all installed
* and loadable (i.e. a 'make install' was done).
* and loadable (i.e. a 'make install' was done).
*/
if (PlatformUtil.isWindowsOS()) {
try {
@ -71,21 +72,21 @@ public class Installer extends ModuleInstall {
}
try {
System.loadLibrary("zlib"); //NON-NLS
logger.log(Level.INFO, "ZLIB library loaded loaded"); //NON-NLS
System.loadLibrary("zlib"); //NON-NLS
logger.log(Level.INFO, "ZLIB library loaded loaded"); //NON-NLS
} catch (UnsatisfiedLinkError e) {
logger.log(Level.SEVERE, "Error loading ZLIB library, ", e); //NON-NLS
logger.log(Level.SEVERE, "Error loading ZLIB library, ", e); //NON-NLS
}
try {
System.loadLibrary("libewf"); //NON-NLS
logger.log(Level.INFO, "EWF library loaded"); //NON-NLS
System.loadLibrary("libewf"); //NON-NLS
logger.log(Level.INFO, "EWF library loaded"); //NON-NLS
} catch (UnsatisfiedLinkError e) {
logger.log(Level.SEVERE, "Error loading EWF library, ", e); //NON-NLS
logger.log(Level.SEVERE, "Error loading EWF library, ", e); //NON-NLS
}
}
}
}
}
public Installer() {
logger.log(Level.INFO, "core installer created"); //NON-NLS
javaFxInit = false;
@ -98,12 +99,14 @@ public class Installer extends ModuleInstall {
/**
* Check if JavaFx initialized
* @return false if java fx not initialized (classes coult not load), true if initialized
*
* @return false if java fx not initialized (classes coult not load), true
* if initialized
*/
public static boolean isJavaFxInited() {
return javaFxInit;
}
private static void initJavaFx() {
//initialize java fx if exists
System.setProperty("javafx.macosx.embedded", "true");
@ -117,7 +120,7 @@ public class Installer extends ModuleInstall {
final String msg = NbBundle.getMessage(Installer.class, "Installer.errorInitJavafx.msg");
final String details = NbBundle.getMessage(Installer.class, "Installer.errorInitJavafx.details");
logger.log(Level.SEVERE, msg
+ details, e);
+ details, e);
WindowManager.getDefault().invokeWhenUIReady(new Runnable() {
@Override
@ -132,11 +135,11 @@ public class Installer extends ModuleInstall {
File pythonModulesDir = new File(PlatformUtil.getUserPythonModulesPath());
pythonModulesDir.mkdir();
}
@Override
public void restored() {
super.restored();
ensurePythonModulesFolderExists();
super.restored();
ensurePythonModulesFolderExists();
initJavaFx();
for (ModuleInstall mi : packageInstallers) {
try {

View File

@ -34,7 +34,7 @@ public final class UserPreferences {
public static final String HIDE_KNOWN_FILES_IN_VIEWS_TREE = "HideKnownFilesInViewsTree"; //NON-NLS
public static final String DISPLAY_TIMES_IN_LOCAL_TIME = "DisplayTimesInLocalTime"; //NON-NLS
public static final String NUMBER_OF_FILE_INGEST_THREADS = "NumberOfFileIngestThreads"; //NON-NLS
// Prevent instantiation.
private UserPreferences() {
}
@ -70,21 +70,21 @@ public final class UserPreferences {
public static void setHideKnownFilesInViewsTree(boolean value) {
preferences.putBoolean(HIDE_KNOWN_FILES_IN_VIEWS_TREE, value);
}
public static boolean displayTimesInLocalTime() {
return preferences.getBoolean(DISPLAY_TIMES_IN_LOCAL_TIME, true);
}
public static void setDisplayTimesInLocalTime(boolean value) {
preferences.putBoolean(DISPLAY_TIMES_IN_LOCAL_TIME, value);
}
}
public static int numberOfFileIngestThreads() {
return preferences.getInt(NUMBER_OF_FILE_INGEST_THREADS, 2);
}
public static void setNumberOfFileIngestThreads(int value) {
preferences.putInt(NUMBER_OF_FILE_INGEST_THREADS, value);
}
}
}

View File

@ -16,39 +16,38 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.corecomponentinterfaces;
import java.beans.PropertyChangeListener;
import org.sleuthkit.datamodel.BlackboardArtifact;
/**
* Additional functionality of viewers
* supporting black board results
* such as the directory tree
* Additional functionality of viewers supporting black board results such as
* the directory tree
*/
public interface BlackboardResultViewer {
public static final String FINISHED_DISPLAY_EVT = "FINISHED_DISPLAY_EVT"; //NON-NLS
/**
* View artifact in a viewer
*
* @param art artifact to view
*/
void viewArtifact(BlackboardArtifact art);
/**
void viewArtifact(BlackboardArtifact art);
/**
* View content associated with the artifact
*
* @param art artifact content to view
*/
void viewArtifactContent(BlackboardArtifact art);
/**
* Add listener to fire an action when viewer is done displaying
* @param l
*/
void addOnFinishedListener(PropertyChangeListener l);
void viewArtifactContent(BlackboardArtifact art);
/**
* Add listener to fire an action when viewer is done displaying
*
* @param l
*/
void addOnFinishedListener(PropertyChangeListener l);
}

View File

@ -26,12 +26,14 @@ import javax.swing.Action;
* menus in Autopsy.
*/
public interface ContextMenuActionsProvider {
/**
* Gets context menu Actions for the currently selected data model objects
* exposed by the NetBeans Lookup of the active TopComponent. Implementers
* should discover the selected objects by calling
* org.openide.util.Utilities.actionsGlobalContext().lookupAll() for the
* Gets context menu Actions for the currently selected data model objects
* exposed by the NetBeans Lookup of the active TopComponent. Implementers
* should discover the selected objects by calling
* org.openide.util.Utilities.actionsGlobalContext().lookupAll() for the
* org.sleuthkit.datamodel classes of interest to the provider.
*
* @return A list, possibly empty, of Action objects.
*/
public List<Action> getActions();

View File

@ -32,7 +32,8 @@ import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.corecomponents.DataContentTopComponent;
/**
* Responsible for opening and closing the core windows when a case is opened and closed.
* Responsible for opening and closing the core windows when a case is opened
* and closed.
*
* @author jantonius
*/
@ -40,13 +41,13 @@ public class CoreComponentControl {
private static final Logger logger = Logger.getLogger(CoreComponentControl.class.getName());
private static final String DIRECTORY_TREE = NbBundle.getMessage(CoreComponentControl.class,
"CoreComponentControl.CTL_DirectoryTreeTopComponent");
"CoreComponentControl.CTL_DirectoryTreeTopComponent");
private static final String FAVORITES = NbBundle.getMessage(CoreComponentControl.class,
"CoreComponentControl.CTL_FavoritesTopComponent");
"CoreComponentControl.CTL_FavoritesTopComponent");
/**
* Opens all TopComponent windows that are needed ({@link DataExplorer}, {@link DataResult}, and
* {@link DataContent})
* Opens all TopComponent windows that are needed
* ({@link DataExplorer}, {@link DataResult}, and {@link DataContent})
*/
public static void openCoreWindows() {
// TODO: there has to be a better way to do this.
@ -77,19 +78,18 @@ public class CoreComponentControl {
}
/**
* Closes all TopComponent windows that needed ({@link DataExplorer}, {@link DataResult}, and
* {@link DataContent}).
*
* Note: The DataContent Top Component must be closed before the Directory Tree
* and Favorites Top Components. Otherwise a NullPointerException will be thrown
* from JFXPanel.
* Closes all TopComponent windows that needed
* ({@link DataExplorer}, {@link DataResult}, and {@link DataContent}).
*
* Note: The DataContent Top Component must be closed before the Directory
* Tree and Favorites Top Components. Otherwise a NullPointerException will
* be thrown from JFXPanel.
*/
public static void closeCoreWindows() {
WindowManager wm = WindowManager.getDefault();
Set<? extends Mode> modes = wm.getModes();
Iterator<? extends Mode> iter = wm.getModes().iterator();
TopComponent directoryTree = null;
TopComponent favorites = null;
String tcName = "";
@ -111,7 +111,7 @@ public class CoreComponentControl {
}
}
}
if (directoryTree != null) {
directoryTree.close();
}

View File

@ -16,7 +16,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.corecomponentinterfaces;
import java.beans.PropertyChangeListener;
@ -32,6 +31,7 @@ public interface DataContent extends PropertyChangeListener {
/**
* Sets the "selected" node in this class
*
* @param selectedNode node to use
*/
void setNode(Node selectedNode);

View File

@ -16,52 +16,51 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.corecomponentinterfaces;
import java.awt.Component;
import org.openide.nodes.Node;
/**
* Interface that DataContentViewer modules must implement.
* These modules analyze an individual file that the user has selected and display
* results in some form of JPanel. We find it easiest to use the NetBeans IDE to first
* make a "JPanel Form" class and then have it implement DataContentViewer. This allows
* you to easily use the UI builder for the layout.
* Interface that DataContentViewer modules must implement. These modules
* analyze an individual file that the user has selected and display results in
* some form of JPanel. We find it easiest to use the NetBeans IDE to first make
* a "JPanel Form" class and then have it implement DataContentViewer. This
* allows you to easily use the UI builder for the layout.
*/
public interface DataContentViewer {
/**
* Autopsy will call this when this panel is focused with the file that
* should be analyzed. When called with null, must
* clear all references to previous nodes.
* Autopsy will call this when this panel is focused with the file that
* should be analyzed. When called with null, must clear all references to
* previous nodes.
*/
public void setNode(Node selectedNode);
/**
* Returns the title of this viewer to display in the tab.
* Returns the title of this viewer to display in the tab.
*/
public String getTitle();
/**
* Returns a short description of this viewer to use as a tool tip for
* its tab.
* Returns a short description of this viewer to use as a tool tip for its
* tab.
*/
public String getToolTip();
/**
* Create and return a new instance of your viewer.
* The reason that this is needed is because the specific
* viewer modules will be found via NetBeans Lookup and
* the type will only be DataContentViewer. This method is
* used to get an instance of your specific type.
* Create and return a new instance of your viewer. The reason that this is
* needed is because the specific viewer modules will be found via NetBeans
* Lookup and the type will only be DataContentViewer. This method is used
* to get an instance of your specific type.
*
* @returns A new instance of the viewer
*/
public DataContentViewer createInstance();
/**
* Return the Swing Component to display.
* Implementations of this method that extend JPanel
* and do a 'return this;'. Otherwise return an internal
* Return the Swing Component to display. Implementations of this method
* that extend JPanel and do a 'return this;'. Otherwise return an internal
* instance of the JPanel.
*/
public Component getComponent();
@ -72,26 +71,29 @@ public interface DataContentViewer {
public void resetComponent();
/**
* Checks whether the given node is supported by the viewer.
* This will be used to enable or disable the tab for the viewer.
* Checks whether the given node is supported by the viewer. This will be
* used to enable or disable the tab for the viewer.
*
* @param node Node to check for support
*
* @return True if the node can be displayed / processed, else false
*/
public boolean isSupported(Node node);
/**
* Checks whether the given viewer is preferred for the Node.
* This is a bit subjective, but the idea is that Autopsy wants to display
* the most relevant tab. The more generic the viewer, the lower
* the return value should be. This will only be called on viewers that
* support the given node.
*
/**
* Checks whether the given viewer is preferred for the Node. This is a bit
* subjective, but the idea is that Autopsy wants to display the most
* relevant tab. The more generic the viewer, the lower the return value
* should be. This will only be called on viewers that support the given
* node.
*
* @param node Node to check for preference
*
* @return an int (0-10) higher return means the viewer has higher priority
* 0 means not supported
* 1 to 2 means the module will display all file types (such as the hex viewer)
* 3-10 are prioritized by Content viewer developer. Modules that operate on very
* few file types should be towards 10.
* 0 means not supported 1 to 2 means the module will display all
* file types (such as the hex viewer) 3-10 are prioritized by
* Content viewer developer. Modules that operate on very few file
* types should be towards 10.
*/
public int isPreferred(Node node);
}

View File

@ -35,20 +35,20 @@ public interface DataResult {
/**
* Gets the unique TopComponent ID of this class.
*
* @return preferredID the unique ID
* @return preferredID the unique ID
*/
public String getPreferredID();
/**
* Sets the title of this TopComponent
*
* @param title the given title (String)
*
* @param title the given title (String)
*/
public void setTitle(String title);
/**
* Sets the descriptive context text at the top of the pane.
*
* @param pathText Descriptive text giving context for the current results
*/
public void setPath(String pathText);
@ -59,10 +59,11 @@ public interface DataResult {
* @return true if it is the main instance, otherwise false
*/
public boolean isMain();
/**
* Get child viewers within this DataResult
* @return
*
* @return
*/
public List<DataResultViewer> getViewers();
}

View File

@ -16,19 +16,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.corecomponentinterfaces;
import java.awt.Component;
import org.openide.nodes.Node;
/**
* Interface for the different viewers that show a set of nodes in the DataResult area.
* AbstractDataResultViewer has default implementations for the action handlers.
*
* Interface for the different viewers that show a set of nodes in the
* DataResult area. AbstractDataResultViewer has default implementations for the
* action handlers.
*
*/
public interface DataResultViewer {
/**
* Set the root node to display in this viewer. When called with null, must
* clear all references to previous nodes.
@ -44,7 +44,7 @@ public interface DataResultViewer {
* Get a new instance of DataResultViewer
*/
public DataResultViewer createInstance();
/**
* Get the Swing component (i.e. JPanel) for this viewer
*/
@ -56,34 +56,39 @@ public interface DataResultViewer {
public void resetComponent();
/**
* Frees the objects that have been allocated by this viewer, in
* preparation for permanently disposing of it.
* Frees the objects that have been allocated by this viewer, in preparation
* for permanently disposing of it.
*/
public void clearComponent();
/**
* Expand node, if supported by the viewed
*
* @param n Node to expand
*/
public void expandNode(Node n);
/**
* Select the given node array
*/
public void setSelectedNodes(Node[] selected);
/**
* Checks whether the currently selected root node
* is supported by this viewer
* Checks whether the currently selected root node is supported by this
* viewer
*
* @param selectedNode the selected node
*
* @return True if supported, else false
*/
public boolean isSupported(Node selectedNode);
/**
* Set a custom content viewer to respond to selection events from this result viewer.
* If not set, the default content viewer is user
* @param contentViewer content viewer to respond to selection events from this viewer
* Set a custom content viewer to respond to selection events from this
* result viewer. If not set, the default content viewer is user
*
* @param contentViewer content viewer to respond to selection events from
* this viewer
*/
public void setContentViewer(DataContent contentViewer);
}

View File

@ -18,73 +18,71 @@
*/
package org.sleuthkit.autopsy.corecomponentinterfaces;
import javax.swing.JPanel;
/**
* Interface used by the Add DataSource wizard to allow different
* types of data sources to be added to a case. Examples of data
* sources include disk images, local files, etc.
*
* The interface provides a uniform mechanism for the Autopsy UI
* to:
* - Collect details from the user about the data source to be processed.
* - Process the data source in the background and add data to the database
* - Provides progress feedback to the user / UI.
* Interface used by the Add DataSource wizard to allow different types of data
* sources to be added to a case. Examples of data sources include disk images,
* local files, etc.
*
* The interface provides a uniform mechanism for the Autopsy UI to: - Collect
* details from the user about the data source to be processed. - Process the
* data source in the background and add data to the database - Provides
* progress feedback to the user / UI.
*/
public interface DataSourceProcessor {
/**
* The DSP Panel may fire Property change events
* The caller must enure to add itself as a listener and
* then react appropriately to the events
* The DSP Panel may fire Property change events The caller must enure to
* add itself as a listener and then react appropriately to the events
*/
enum DSP_PANEL_EVENT {
UPDATE_UI, ///< the content of JPanel has changed that MAY warrant updates to the caller UI
UPDATE_UI, ///< the content of JPanel has changed that MAY warrant updates to the caller UI
FOCUS_NEXT ///< the caller UI may move focus the the next UI element, following the panel.
};
/**
* Returns the type of Data Source it handles.
* This name gets displayed in the drop-down listbox
*/
/**
* Returns the type of Data Source it handles. This name gets displayed in
* the drop-down listbox
*/
String getDataSourceType();
/**
* Returns the picker panel to be displayed along with any other
* runtime options supported by the data source handler. The
* DSP is responsible for storing the settings so that a later
* call to run() will have the user-specified settings.
*
* Should be less than 544 pixels wide and 173 pixels high.
*/
/**
* Returns the picker panel to be displayed along with any other runtime
* options supported by the data source handler. The DSP is responsible for
* storing the settings so that a later call to run() will have the
* user-specified settings.
*
* Should be less than 544 pixels wide and 173 pixels high.
*/
JPanel getPanel();
/**
* Called to validate the input data in the panel.
* Returns true if no errors, or
* Returns false if there is an error.
*/
/**
* Called to validate the input data in the panel. Returns true if no
* errors, or Returns false if there is an error.
*/
boolean isPanelValid();
/**
* Called to invoke the handling of data source in the background.
* Returns after starting the background thread.
*
* @param progressPanel progress panel to be updated while processing
* @param dspCallback Contains the callback method DataSourceProcessorCallback.done() that the DSP must call when the background thread finishes with errors and status.
*/
/**
* Called to invoke the handling of data source in the background. Returns
* after starting the background thread.
*
* @param progressPanel progress panel to be updated while processing
* @param dspCallback Contains the callback method
* DataSourceProcessorCallback.done() that the DSP must
* call when the background thread finishes with errors
* and status.
*/
void run(DataSourceProcessorProgressMonitor progressPanel, DataSourceProcessorCallback dspCallback);
/**
* Called to cancel the background processing.
*/
/**
* Called to cancel the background processing.
*/
void cancel();
/**
* Called to reset/reinitialize the DSP.
*/
/**
* Called to reset/reinitialize the DSP.
*/
void reset();
}

View File

@ -32,20 +32,22 @@ import org.sleuthkit.datamodel.Content;
public abstract class DataSourceProcessorCallback {
public enum DataSourceProcessorResult {
NO_ERRORS, ///< No errors were encountered while ading the data source
NO_ERRORS, ///< No errors were encountered while ading the data source
CRITICAL_ERRORS, ///< No data was added to the database. There were fundamental errors processing the data (such as no data or system failure).
NONCRITICAL_ERRORS, ///< There was data added to the database, but there were errors from data corruption or a small number of minor issues.
};
/**
* Called by a DSP implementation when it is done adding a data source
* to the database. Users of the DSP can override this method if they do
* not want to be notified on the EDT. Otherwise, this method will call
* doneEDT() with the same arguments.
* @param result Code for status
* @param errList List of error strings
* @param newContents List of root Content objects that were added to database. Typically only one is given.
* Called by a DSP implementation when it is done adding a data source to
* the database. Users of the DSP can override this method if they do not
* want to be notified on the EDT. Otherwise, this method will call
* doneEDT() with the same arguments.
*
* @param result Code for status
* @param errList List of error strings
* @param newContents List of root Content objects that were added to
* database. Typically only one is given.
*/
public void done(DataSourceProcessorResult result, List<String> errList, List<Content> newContents) {
@ -63,13 +65,14 @@ public abstract class DataSourceProcessorCallback {
}
/**
* Called by done() if the default implementation is used. Users of DSPs
* Called by done() if the default implementation is used. Users of DSPs
* that have UI updates to do after the DSP is finished adding the DS can
* implement this method to receive the updates on the EDT.
*
* @param result Code for status
* @param errList List of error strings
* @param newContents List of root Content objects that were added to database. Typically only one is given.
*/
* @param result Code for status
* @param errList List of error strings
* @param newContents List of root Content objects that were added to
* database. Typically only one is given.
*/
public abstract void doneEDT(DataSourceProcessorResult result, List<String> errList, List<Content> newContents);
};

View File

@ -19,15 +19,15 @@
package org.sleuthkit.autopsy.corecomponentinterfaces;
/**
* An GUI agnostic DataSourceProcessorProgressMonitor interface for DataSourceProcesssors to
* indicate progress.
* It models after a JProgressbar though it could use any underlying implementation (or NoOps)
* An GUI agnostic DataSourceProcessorProgressMonitor interface for
* DataSourceProcesssors to indicate progress. It models after a JProgressbar
* though it could use any underlying implementation (or NoOps)
*/
public interface DataSourceProcessorProgressMonitor {
void setIndeterminate(boolean indeterminate);
void setProgress(int progress);
void setProgressText(String text);
void setProgressText(String text);
}

View File

@ -28,7 +28,8 @@ import org.openide.awt.ActionRegistration;
import org.openide.util.NbBundle;
/**
* Action to open custom implementation of the "About" window from the Help menu.
* Action to open custom implementation of the "About" window from the Help
* menu.
*/
@ActionID(id = "org.sleuthkit.autopsy.corecomponents.AboutWindowAction", category = "Help")
@ActionRegistration(displayName = "#CTL_CustomAboutAction", iconInMenu = true, lazy = false)

View File

@ -63,8 +63,8 @@ public final class AboutWindowPanel extends JPanel implements HyperlinkListener
initComponents();
logoLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
description.setText(org.openide.util.NbBundle.getMessage(AboutWindowPanel.class,
"LBL_Description", new Object[]{getProductVersionValue(), getJavaValue(), getVMValue(),
getOperatingSystemValue(), getEncodingValue(), getSystemLocaleValue(), getUserDirValue(), getSleuthKitVersionValue(), Version.getNetbeansBuild(), Version.getBuildType().toString()}));
"LBL_Description", new Object[]{getProductVersionValue(), getJavaValue(), getVMValue(),
getOperatingSystemValue(), getEncodingValue(), getSystemLocaleValue(), getUserDirValue(), getSleuthKitVersionValue(), Version.getNetbeansBuild(), Version.getBuildType().toString()}));
description.addHyperlinkListener(this);
copyright.addHyperlinkListener(this);
copyright.setBackground(getBackground());
@ -74,7 +74,6 @@ public final class AboutWindowPanel extends JPanel implements HyperlinkListener
}
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
@ -228,30 +227,30 @@ private void logoLabelMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:e
private static String getOperatingSystemValue() {
return NbBundle.getMessage(AboutWindowPanel.class, "Format_OperatingSystem_Value",
System.getProperty("os.name", //NON-NLS
NbBundle.getMessage(AboutWindowPanel.class,
"ProductInformationPanel.propertyUnknown.text")),
System.getProperty("os.version", //NON-NLS
NbBundle.getMessage(AboutWindowPanel.class,
"ProductInformationPanel.propertyUnknown.text")),
System.getProperty("os.arch", //NON-NLS
NbBundle.getMessage(AboutWindowPanel.class,
"ProductInformationPanel.propertyUnknown.text")));
System.getProperty("os.name", //NON-NLS
NbBundle.getMessage(AboutWindowPanel.class,
"ProductInformationPanel.propertyUnknown.text")),
System.getProperty("os.version", //NON-NLS
NbBundle.getMessage(AboutWindowPanel.class,
"ProductInformationPanel.propertyUnknown.text")),
System.getProperty("os.arch", //NON-NLS
NbBundle.getMessage(AboutWindowPanel.class,
"ProductInformationPanel.propertyUnknown.text")));
}
private static String getJavaValue() {
return System.getProperty("java.version", //NON-NLS
NbBundle.getMessage(AboutWindowPanel.class,
"ProductInformationPanel.propertyUnknown.text"));
NbBundle.getMessage(AboutWindowPanel.class,
"ProductInformationPanel.propertyUnknown.text"));
}
private static String getVMValue() {
return NbBundle.getMessage(AboutWindowPanel.class,
"ProductInformationPanel.getVMValue.text",
System.getProperty("java.vm.name", //NON-NLS
NbBundle.getMessage(AboutWindowPanel.class,
"ProductInformationPanel.propertyUnknown.text")),
System.getProperty("java.vm.version", "")); //NON-NLS
"ProductInformationPanel.getVMValue.text",
System.getProperty("java.vm.name", //NON-NLS
NbBundle.getMessage(AboutWindowPanel.class,
"ProductInformationPanel.propertyUnknown.text")),
System.getProperty("java.vm.version", "")); //NON-NLS
}
private static String getSystemLocaleValue() {
@ -265,7 +264,7 @@ private void logoLabelMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:e
private static String getEncodingValue() {
return System.getProperty("file.encoding", //NON-NLS
NbBundle.getMessage(AboutWindowPanel.class, "ProductInformationPanel.propertyUnknown.text"));
NbBundle.getMessage(AboutWindowPanel.class, "ProductInformationPanel.propertyUnknown.text"));
}
public void setCopyright(String text) {

View File

@ -31,12 +31,12 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.DataResultViewer;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* This class provides a default implementation of selected methods of the
* DataResultViewer interface. Derived classes will be Swing JPanel objects.
* Additionally, the ExplorerManager.Provider interface is implemented to
* supply an ExplorerManager to derived classes and their child components.
* This class provides a default implementation of selected methods of the
* DataResultViewer interface. Derived classes will be Swing JPanel objects.
* Additionally, the ExplorerManager.Provider interface is implemented to supply
* an ExplorerManager to derived classes and their child components.
*/
abstract class AbstractDataResultViewer extends JPanel implements DataResultViewer, Provider {
abstract class AbstractDataResultViewer extends JPanel implements DataResultViewer, Provider {
private static final Logger logger = Logger.getLogger(AbstractDataResultViewer.class.getName());
protected transient ExplorerManager em;
@ -49,19 +49,19 @@ import org.sleuthkit.autopsy.coreutils.Logger;
/**
* This constructor is intended to allow an AbstractDataResultViewer to use
* an ExplorerManager provided by a TopComponent, allowing Node selections
* to be available to Actions via the action global context lookup when
* the TopComponent has focus. The ExplorerManager must be present when the
* to be available to Actions via the action global context lookup when the
* TopComponent has focus. The ExplorerManager must be present when the
* object is constructed so that its child components can discover it using
* the ExplorerManager.find() method.
* the ExplorerManager.find() method.
*/
public AbstractDataResultViewer(ExplorerManager explorerManager) {
this.em = explorerManager;
initialize();
}
/**
* This constructor can be used by AbstractDataResultViewers that do not
* need to make Node selections available to Actions via the action global
* need to make Node selections available to Actions via the action global
* context lookup.
*/
public AbstractDataResultViewer() {
@ -72,9 +72,9 @@ import org.sleuthkit.autopsy.coreutils.Logger;
private void initialize() {
//DataContent is designed to return only the default viewer from lookup
//use the default one unless set otherwise
contentViewer = Lookup.getDefault().lookup(DataContent.class);
contentViewer = Lookup.getDefault().lookup(DataContent.class);
}
@Override
public void clearComponent() {
}

View File

@ -11,38 +11,43 @@ import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* Displays a panel in a new clean dialog. A clean dialog contains nothing
* but the panel given to it. No additional buttons or features, except
* the default close operation, which is set to dispose.
* Displays a panel in a new clean dialog. A clean dialog contains nothing but
* the panel given to it. No additional buttons or features, except the default
* close operation, which is set to dispose.
*/
public class AdvancedConfigurationCleanDialog extends javax.swing.JDialog {
public class AdvancedConfigurationCleanDialog extends javax.swing.JDialog {
/** Creates new form AdvancedConfigurationDialog */
/**
* Creates new form AdvancedConfigurationDialog
*/
public AdvancedConfigurationCleanDialog() {
this(false);
}
/** Creates new form AdvancedConfigurationDialog */
/**
* Creates new form AdvancedConfigurationDialog
*/
public AdvancedConfigurationCleanDialog(boolean resizable) {
super(new JFrame(), true);
setResizable(resizable);
if(resizable) {
if (resizable) {
this.setIconImage(null);
}
initComponents();
}
/**
* Display the given panel on a clean dialog.
*
* @param panel the panel to display
*/
public void display(JPanel panel) {
this.setTitle(panel.getName());
panel.setAlignmentX(Component.CENTER_ALIGNMENT);
this.add(panel, 0);
this.pack();
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
// set the popUp window / JFrame
int w = this.getSize().width;
@ -50,10 +55,10 @@ import javax.swing.JPanel;
// 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);
}
/**
* Close the dialog.
*/

View File

@ -37,30 +37,33 @@ import javax.swing.JPanel;
*/
public class AdvancedConfigurationDialog extends javax.swing.JDialog {
/** Creates new form AdvancedConfigurationDialog */
/**
* Creates new form AdvancedConfigurationDialog
*/
public AdvancedConfigurationDialog() {
this(false);
}
/** Creates new form AdvancedConfigurationDialog */
/**
* Creates new form AdvancedConfigurationDialog
*/
public AdvancedConfigurationDialog(boolean resizable) {
super(new JFrame(), true);
setResizable(resizable);
if(resizable) {
if (resizable) {
this.setIconImage(null);
}
initComponents();
}
public void display(JPanel panel) {
this.setTitle(panel.getName());
panel.setAlignmentX(Component.CENTER_ALIGNMENT);
//applyButton.setAlignmentX(Component.CENTER_ALIGNMENT);
this.add(panel, 0);
this.pack();
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
// set the popUp window / JFrame
int w = this.getSize().width;
@ -68,14 +71,14 @@ public class AdvancedConfigurationDialog extends javax.swing.JDialog {
// 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);
}
/** 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.
/**
* 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

View File

@ -67,7 +67,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
recommendedFileIngestThreadCount = 1;
}
numberOfFileIngestThreadsComboBox.setModel(new DefaultComboBoxModel<>(fileIngestThreadCountChoices));
restartRequiredLabel.setText(NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.restartRequiredLabel.text", recommendedFileIngestThreadCount));
restartRequiredLabel.setText(NbBundle.getMessage(AutopsyOptionsPanel.class, "AutopsyOptionsPanel.restartRequiredLabel.text", recommendedFileIngestThreadCount));
// TODO listen to changes in form fields and call controller.changed()
}
@ -80,7 +80,7 @@ final class AutopsyOptionsPanel extends javax.swing.JPanel {
boolean useLocalTime = UserPreferences.displayTimesInLocalTime();
useLocalTimeRB.setSelected(useLocalTime);
useGMTTimeRB.setSelected(!useLocalTime);
numberOfFileIngestThreadsComboBox.setSelectedItem(UserPreferences.numberOfFileIngestThreads());
numberOfFileIngestThreadsComboBox.setSelectedItem(UserPreferences.numberOfFileIngestThreads());
}
void store() {

View File

@ -40,60 +40,60 @@ import org.sleuthkit.datamodel.TskCoreException;
/**
*
*/
public class DataContentPanel extends javax.swing.JPanel implements DataContent, ChangeListener {
public class DataContentPanel extends javax.swing.JPanel implements DataContent, ChangeListener {
private static Logger logger = Logger.getLogger(DataContentPanel.class.getName());
private final List<UpdateWrapper> viewers = new ArrayList<>();;
private final List<UpdateWrapper> viewers = new ArrayList<>();
;
private Node currentNode;
private final boolean isMain;
private boolean listeningToTabbedPane = false;
private boolean listeningToTabbedPane = false;
/**
* Creates new DataContentPanel panel
* The main data content panel can only be created by the data content top component,
* thus this constructor is not public.
*
* Use the createInstance factory method to create an external viewer data content panel.
*
* Creates new DataContentPanel panel The main data content panel can only
* be created by the data content top component, thus this constructor is
* not public.
*
* Use the createInstance factory method to create an external viewer data
* content panel.
*
*/
DataContentPanel(boolean isMain) {
this.isMain = isMain;
initComponents();
// add all implementors of DataContentViewer and put them in the tabbed pane
Collection<? extends DataContentViewer> dcvs = Lookup.getDefault().lookupAll(DataContentViewer.class);
for (DataContentViewer factory : dcvs) {
DataContentViewer dcv;
if (isMain) {
//use the instance from Lookup for the main viewer
dcv = factory;
}
else {
dcv = factory.createInstance();
dcv = factory;
} else {
dcv = factory.createInstance();
}
viewers.add(new UpdateWrapper(dcv));
jTabbedPane1.addTab(dcv.getTitle(), null,
dcv.getComponent(), dcv.getToolTip());
}
// disable the tabs
int numTabs = jTabbedPane1.getTabCount();
for (int tab = 0; tab < numTabs; ++tab) {
jTabbedPane1.setEnabledAt(tab, false);
}
}
/**
* Factory method to create an external (not main window) data content panel
* to be used in an external window
*
*
* @return a new instance of a data content panel
*/
public static DataContentPanel createInstance() {
return new DataContentPanel(false);
}
public JTabbedPane getTabPanels() {
return jTabbedPane1;
}
@ -131,8 +131,7 @@ import org.sleuthkit.datamodel.TskCoreException;
// change the cursor to "waiting cursor" for this operation
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
try {
String defaultName = NbBundle.getMessage(DataContentTopComponent.class, "CTL_DataContentTopComponent");
// set the file path
if (selectedNode == null) {
@ -160,21 +159,21 @@ import org.sleuthkit.datamodel.TskCoreException;
this.setCursor(null);
}
}
/**
* Resets the tabs based on the selected Node. If the selected node is null
* or not supported, disable that tab as well.
*
* @param selectedNode the selected content Node
* @param selectedNode the selected content Node
*/
public void setupTabs(Node selectedNode) {
// Deferring becoming a listener to the tabbed pane until this point
// eliminates handling a superfluous stateChanged event during construction.
if (listeningToTabbedPane == false) {
jTabbedPane1.addChangeListener(this);
jTabbedPane1.addChangeListener(this);
listeningToTabbedPane = true;
}
int currTabIndex = jTabbedPane1.getSelectedIndex();
int totalTabs = jTabbedPane1.getTabCount();
int maxPreferred = 0;
@ -188,7 +187,7 @@ import org.sleuthkit.datamodel.TskCoreException;
jTabbedPane1.setEnabledAt(i, false);
} else {
jTabbedPane1.setEnabledAt(i, true);
// remember the viewer with the highest preference value
int currentPreferred = dcv.isPreferred(selectedNode);
if (currentPreferred > maxPreferred) {
@ -197,19 +196,18 @@ import org.sleuthkit.datamodel.TskCoreException;
}
}
}
// let the user decide if we should stay with the current viewer
int tabIndex = UserPreferences.keepPreferredContentViewer() ? currTabIndex : preferredViewerIndex;
UpdateWrapper dcv = viewers.get(tabIndex);
// this is really only needed if no tabs were enabled
if (jTabbedPane1.isEnabledAt(tabIndex) == false) {
dcv.resetComponent();
}
else {
} else {
dcv.setNode(selectedNode);
}
// set the tab to the one the user wants, then set that viewer's node.
jTabbedPane1.setSelectedIndex(tabIndex);
}
@ -265,10 +263,10 @@ import org.sleuthkit.datamodel.TskCoreException;
boolean isSupported(Node node) {
return this.wrapped.isSupported(node);
}
int isPreferred(Node node) {
return this.wrapped.isPreferred(node);
}
}
}

View File

@ -32,15 +32,16 @@ import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContent;
/**
* Top component that organizes all of the data content viewers. Doing a lookup on this class will
* always return the default instance (which is created at startup).
* Top component that organizes all of the data content viewers. Doing a lookup
* on this class will always return the default instance (which is created at
* startup).
*/
// Registered as a service provider in layer.xml
//@TopComponent.Description(preferredID = "DataContentTopComponent")
//@TopComponent.Registration(mode = "output", openAtStartup = true)
//@TopComponent.OpenActionRegistration(displayName = "#CTL_DataContentAction", preferredID = "DataContentTopComponent")
public final class DataContentTopComponent extends TopComponent implements DataContent {
private static Logger logger = Logger.getLogger(DataContentTopComponent.class.getName());
// reference to the "default" TC that always stays open
@ -55,26 +56,28 @@ public final class DataContentTopComponent extends TopComponent implements DataC
private static final String PREFERRED_ID = "DataContentTopComponent"; //NON-NLS
private static final String DEFAULT_NAME = NbBundle.getMessage(DataContentTopComponent.class, "CTL_DataContentTopComponent");
private static final String TOOLTIP_TEXT = NbBundle.getMessage(DataContentTopComponent.class, "HINT_DataContentTopComponent");
private DataContentTopComponent(boolean isDefault, String name) {
initComponents();
setName(name);
setToolTipText(TOOLTIP_TEXT);
this.isDefault = isDefault;
dataContentPanel = new DataContentPanel(isDefault);
add(dataContentPanel);
putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.valueOf(isDefault)); // prevent option to close compoment in GUI
logger.log(Level.INFO, "Created DataContentTopComponent instance: " + this); //NON-NLS
}
/**
* This createInstance method is used to create an undocked instance
* for the "View in New Window" feature.
* @param filePath path of given file node
* This createInstance method is used to create an undocked instance for the
* "View in New Window" feature.
*
* @param filePath path of given file node
* @param givenNode node to view content of
*
* @return newly undocked instance
*/
public static DataContentTopComponent createUndocked(String filePath, Node givenNode) {
@ -88,10 +91,10 @@ public final class DataContentTopComponent extends TopComponent implements DataC
return dctc;
}
/** 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.
/**
* 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() {
@ -102,9 +105,10 @@ public final class DataContentTopComponent extends TopComponent implements DataC
// End of variables declaration//GEN-END:variables
/**
* Gets default instance. Do not use directly: reserved for *.settings files only,
* i.e. deserialization routines; otherwise you could get a non-deserialized defaultInstance.
* To obtain the singleton instance, use {@link #findInstance}.
* Gets default instance. Do not use directly: reserved for *.settings files
* only, i.e. deserialization routines; otherwise you could get a
* non-deserialized defaultInstance. To obtain the singleton instance, use
* {@link #findInstance}.
*/
public static synchronized DataContentTopComponent getDefault() {
if (defaultInstance == null) {
@ -114,7 +118,8 @@ public final class DataContentTopComponent extends TopComponent implements DataC
}
/**
* Obtain the default DataContentTopComponent defaultInstance. Never call {@link #getDefault} directly!
* Obtain the default DataContentTopComponent defaultInstance. Never call
* {@link #getDefault} directly!
*/
public static synchronized DataContentTopComponent findInstance() {
TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
@ -144,7 +149,7 @@ public final class DataContentTopComponent extends TopComponent implements DataC
public void componentClosed() {
dataContentPanel.setNode(null);
if (!this.isDefault) {
newWindowList.remove(this);
}
@ -175,6 +180,7 @@ public final class DataContentTopComponent extends TopComponent implements DataC
/**
* Get the tab pane
*
* @return tab pane with individual DataContentViewers
*/
public JTabbedPane getTabPanels() {
@ -183,6 +189,7 @@ public final class DataContentTopComponent extends TopComponent implements DataC
/**
* Returns a list of the non-default (main) TopComponents
*
* @return
*/
public static List<DataContentTopComponent> getNewWindowList() {

View File

@ -16,7 +16,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.corecomponents;
import java.awt.*;
@ -47,12 +46,13 @@ import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskException;
/**
* Instances of this class display the BlackboardArtifacts associated with the Content represented by a Node.
* Each BlackboardArtifact is rendered as an HTML representation of its BlackboardAttributes.
* Instances of this class display the BlackboardArtifacts associated with the
* Content represented by a Node. Each BlackboardArtifact is rendered as an HTML
* representation of its BlackboardAttributes.
*/
@ServiceProvider(service = DataContentViewer.class, position=3)
public class DataContentViewerArtifact extends javax.swing.JPanel implements DataContentViewer{
@ServiceProvider(service = DataContentViewer.class, position = 3)
public class DataContentViewerArtifact extends javax.swing.JPanel implements DataContentViewer {
private final static Logger logger = Logger.getLogger(DataContentViewerArtifact.class.getName());
private final static String WAIT_TEXT = NbBundle.getMessage(DataContentViewerArtifact.class, "DataContentViewerArtifact.waitText");
private final static String ERROR_TEXT = NbBundle.getMessage(DataContentViewerArtifact.class, "DataContentViewerArtifact.errorText");
@ -61,17 +61,17 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
private final Object lock = new Object();
private List<ArtifactStringContent> artifactContentStrings; // Accessed by multiple threads, use getArtifactContentStrings() and setArtifactContentStrings()
SwingWorker<ViewUpdate, Void> currentTask; // Accessed by multiple threads, use startNewTask()
public DataContentViewerArtifact() {
initComponents();
customizeComponents();
resetComponents();
}
/** 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.
/**
* 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
@ -207,13 +207,13 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
private void nextPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nextPageButtonActionPerformed
currentPage = currentPage + 1;
currentPageLabel.setText(Integer.toString(currentPage));
currentPageLabel.setText(Integer.toString(currentPage));
startNewTask(new SelectedArtifactChangedTask(currentPage));
}//GEN-LAST:event_nextPageButtonActionPerformed
private void prevPageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_prevPageButtonActionPerformed
currentPage = currentPage - 1;
currentPageLabel.setText(Integer.toString(currentPage));
currentPageLabel.setText(Integer.toString(currentPage));
startNewTask(new SelectedArtifactChangedTask(currentPage));
}//GEN-LAST:event_prevPageButtonActionPerformed
@ -233,21 +233,22 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
private javax.swing.JLabel totalPageLabel;
// End of variables declaration//GEN-END:variables
private void customizeComponents(){
private void customizeComponents() {
outputViewPane.setComponentPopupMenu(rightClickMenu);
ActionListener actList = new ActionListener(){
ActionListener actList = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e){
public void actionPerformed(ActionEvent e) {
JMenuItem jmi = (JMenuItem) e.getSource();
if(jmi.equals(copyMenuItem))
if (jmi.equals(copyMenuItem)) {
outputViewPane.copy();
else if(jmi.equals(selectAllMenuItem))
} else if (jmi.equals(selectAllMenuItem)) {
outputViewPane.selectAll();
}
}
};
copyMenuItem.addActionListener(actList);
selectAllMenuItem.addActionListener(actList);
Utilities.configureTextPaneAsHtml(outputViewPane);
}
@ -263,26 +264,26 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
nextPageButton.setEnabled(false);
currentNode = null;
}
@Override
public void setNode(Node selectedNode) {
if (currentNode == selectedNode) {
return;
}
currentNode = selectedNode;
// Make sure there is a node. Null might be passed to reset the viewer.
if (selectedNode == null) {
return;
}
// Make sure the node is of the correct type.
Lookup lookup = selectedNode.getLookup();
Content content = lookup.lookup(Content.class);
if (content == null) {
return;
return;
}
startNewTask(new SelectedNodeChangedTask(selectedNode));
}
@ -310,19 +311,18 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
public void resetComponent() {
resetComponents();
}
@Override
public boolean isSupported(Node node) {
if (node == null) {
return false;
}
Content content = node.getLookup().lookup(Content.class);
if(content != null) {
Content content = node.getLookup().lookup(Content.class);
if (content != null) {
try {
return content.getAllArtifactsCount() > 0;
}
catch (TskException ex) {
} catch (TskException ex) {
logger.log(Level.WARNING, "Couldn't get count of BlackboardArtifacts for content", ex); //NON-NLS
}
}
@ -335,69 +335,75 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
// low priority if node doesn't have an artifact (meaning it was found from normal directory
// browsing, or if the artifact is something that means the user really wants to see the original
// file and not more details about the artifact
if ((artifact == null) ||
(artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID()) ||
(artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID())) {
if ((artifact == null)
|| (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID())
|| (artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID())) {
return 3;
}
else {
} else {
return 5;
}
}
/**
* Instances of this class are simple containers for view update information generated by a background thread.
* Instances of this class are simple containers for view update information
* generated by a background thread.
*/
private class ViewUpdate {
int numberOfPages;
int currentPage;
String text;
ViewUpdate(int numberOfPages, int currentPage, String text) {
this.currentPage = currentPage;
this.numberOfPages = numberOfPages;
this.text = text;
}
}
/**
* Called from queued SwingWorker done() methods on the EDT thread, so doesn't need to be synchronized.
* @param viewUpdate A simple container for display update information from a background thread.
* Called from queued SwingWorker done() methods on the EDT thread, so
* doesn't need to be synchronized.
*
* @param viewUpdate A simple container for display update information from
* a background thread.
*/
private void updateView(ViewUpdate viewUpdate) {
private void updateView(ViewUpdate viewUpdate) {
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
nextPageButton.setEnabled(viewUpdate.currentPage < viewUpdate.numberOfPages);
prevPageButton.setEnabled(viewUpdate.currentPage > 1);
currentPage = viewUpdate.currentPage;
totalPageLabel.setText(Integer.toString(viewUpdate.numberOfPages));
currentPageLabel.setText(Integer.toString(currentPage));
currentPageLabel.setText(Integer.toString(currentPage));
// @@@ This can take a long time. Perhaps a faster HTML renderer can be found.
// Note that the rendering appears to be done on a background thread, since the
// wait cursor reset below happens before the new text hits the JTextPane. On the
// other hand, the UI is unresponsive...
outputViewPane.setText(viewUpdate.text);
outputViewPane.setText(viewUpdate.text);
outputViewPane.moveCaretPosition(0);
this.setCursor(null);
}
}
/**
* Start a new task on its own background thread, canceling the previous task.
* @param task A new SwingWorker object to execute as a background thread.
* Start a new task on its own background thread, canceling the previous
* task.
*
* @param task A new SwingWorker object to execute as a background thread.
*/
private synchronized void startNewTask(SwingWorker<ViewUpdate, Void> task) {
outputViewPane.setText(WAIT_TEXT);
private synchronized void startNewTask(SwingWorker<ViewUpdate, Void> task) {
outputViewPane.setText(WAIT_TEXT);
outputViewPane.moveCaretPosition(0);
// The output of the previous task is no longer relevant.
if (currentTask != null) {
// This call sets a cancellation flag. It does not terminate the background thread running the task.
// The task must check the cancellation flag and react appropriately.
currentTask.cancel(false);
}
// Start the new task.
currentTask = task;
currentTask.execute();
@ -405,6 +411,7 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
/**
* Populate the cache of artifact represented as strings.
*
* @param artifactStrings A list of string representations of artifacts.
*/
private void setArtifactContentStrings(List<ArtifactStringContent> artifactStrings) {
@ -412,9 +419,10 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
this.artifactContentStrings = artifactStrings;
}
}
/**
* Retrieve the cache of artifact represented as strings.
*
* @return A list of string representations of artifacts.
*/
private List<ArtifactStringContent> getArtifactContentStrings() {
@ -422,45 +430,46 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
return artifactContentStrings;
}
}
/**
* Instances of this class use a background thread to generate a ViewUpdate when a node is selected,
* changing the set of blackboard artifacts ("results") to be displayed.
* Instances of this class use a background thread to generate a ViewUpdate
* when a node is selected, changing the set of blackboard artifacts
* ("results") to be displayed.
*/
private class SelectedNodeChangedTask extends SwingWorker<ViewUpdate, Void> {
private final Node selectedNode;
SelectedNodeChangedTask(Node selectedNode) {
this.selectedNode = selectedNode;
}
@Override
protected ViewUpdate doInBackground() {
protected ViewUpdate doInBackground() {
// Get the lookup for the node for access to its underlying content and
// blackboard artifact, if any.
Lookup lookup = selectedNode.getLookup();
// Get the content.
Content content = lookup.lookup(Content.class);
if (content == null) {
return new ViewUpdate(getArtifactContentStrings().size(), currentPage, ERROR_TEXT);
return new ViewUpdate(getArtifactContentStrings().size(), currentPage, ERROR_TEXT);
}
// Get all of the blackboard artifacts associated with the content. These are what this
// viewer displays.
ArrayList<BlackboardArtifact> artifacts;
try {
artifacts = content.getAllArtifacts();
}
catch (TskException ex) {
} catch (TskException ex) {
logger.log(Level.WARNING, "Couldn't get artifacts", ex); //NON-NLS
return new ViewUpdate(getArtifactContentStrings().size(), currentPage, ERROR_TEXT);
return new ViewUpdate(getArtifactContentStrings().size(), currentPage, ERROR_TEXT);
}
if (isCancelled()) {
return null;
}
// Build the new artifact strings cache.
ArrayList<ArtifactStringContent> artifactStrings = new ArrayList<>();
for (BlackboardArtifact artifact : artifacts) {
@ -479,37 +488,36 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
// if the artifact has an ASSOCIATED ARTIFACT, then we display the associated artifact instead
try {
for (BlackboardAttribute attr : artifact.getAttributes()) {
if (attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()) {
long assocArtifactId = attr.getValueLong();
int assocArtifactIndex = -1;
for (BlackboardArtifact art: artifacts) {
if (assocArtifactId == art.getArtifactID()) {
assocArtifactIndex = artifacts.indexOf(art);
break;
}
}
if (assocArtifactIndex >= 0) {
if (attr.getAttributeTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()) {
long assocArtifactId = attr.getValueLong();
int assocArtifactIndex = -1;
for (BlackboardArtifact art : artifacts) {
if (assocArtifactId == art.getArtifactID()) {
assocArtifactIndex = artifacts.indexOf(art);
break;
}
}
if (assocArtifactIndex >= 0) {
index = assocArtifactIndex;
}
break;
}
break;
}
}
}
catch (TskCoreException ex) {
} catch (TskCoreException ex) {
logger.log(Level.WARNING, "Couldn't get associated artifact to display in Content Viewer.", ex); //NON-NLS
}
}
}
}
}
if (isCancelled()) {
return null;
}
// Add one to the index of the artifact string for the corresponding page index. Note that the getString() method
// of ArtifactStringContent does a lazy fetch of the attributes of the correspoding artifact and represents them as
// HTML.
ViewUpdate viewUpdate = new ViewUpdate(artifactStrings.size(), index + 1, artifactStrings.get(index).getString());
ViewUpdate viewUpdate = new ViewUpdate(artifactStrings.size(), index + 1, artifactStrings.get(index).getString());
// It may take a considerable amount of time to fetch the attributes of the selected artifact and render them
// as HTML, so check for cancellation.
@ -519,10 +527,10 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
// Update the artifact strings cache.
setArtifactContentStrings(artifactStrings);
return viewUpdate;
}
@Override
protected void done() {
if (!isCancelled()) {
@ -531,25 +539,26 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
if (viewUpdate != null) {
updateView(viewUpdate);
}
}
catch (InterruptedException | ExecutionException ex) {
} catch (InterruptedException | ExecutionException ex) {
logger.log(Level.WARNING, "Artifact display task unexpectedly interrupted or failed", ex); //NON-NLS
}
}
}
}
}
}
/**
* Instances of this class use a background thread to generate a ViewUpdate when the user pages the view
* to look at another blackboard artifact ("result").
* Instances of this class use a background thread to generate a ViewUpdate
* when the user pages the view to look at another blackboard artifact
* ("result").
*/
private class SelectedArtifactChangedTask extends SwingWorker<ViewUpdate, Void> {
private final int pageIndex;
SelectedArtifactChangedTask(final int pageIndex) {
this.pageIndex = pageIndex;
}
@Override
protected ViewUpdate doInBackground() {
// Get the artifact string to display from the cache. Note that one must be subtracted from the
@ -560,16 +569,16 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
// The getString() method of ArtifactStringContent does a lazy fetch of the attributes of the
// correspoding artifact and represents them as HTML.
String artifactString = artifactStringContent.getString();
// It may take a considerable amount of time to fetch the attributes of the selected artifact and render them
// as HTML, so check for cancellation.
if (isCancelled()) {
return null;
}
return new ViewUpdate(artifactStrings.size(), pageIndex, artifactString);
}
@Override
protected void done() {
if (!isCancelled()) {
@ -578,11 +587,10 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
if (viewUpdate != null) {
updateView(viewUpdate);
}
}
catch (InterruptedException | ExecutionException ex) {
} catch (InterruptedException | ExecutionException ex) {
logger.log(Level.WARNING, "Artifact display task unexpectedly interrupted or failed", ex); //NON-NLS
}
}
}
}
}
}
}

View File

@ -42,6 +42,7 @@ import org.sleuthkit.datamodel.TskException;
*/
@ServiceProvider(service = DataContentViewer.class, position = 1)
public class DataContentViewerHex extends javax.swing.JPanel implements DataContentViewer {
private static final long pageLength = 16384;
private final byte[] data = new byte[(int) pageLength];
private static int currentPage = 1;
@ -275,7 +276,7 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
private void goToPageTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_goToPageTextFieldActionPerformed
String pageNumberStr = goToPageTextField.getText();
int pageNumber = 0;
try {
pageNumber = Integer.parseInt(pageNumberStr);
} catch (NumberFormatException ex) {
@ -283,22 +284,26 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
}
if (pageNumber > totalPages || pageNumber < 1) {
JOptionPane.showMessageDialog(this,
NbBundle.getMessage(this.getClass(),
"DataContentViewerHex.goToPageTextField.msgDlg",
totalPages),
NbBundle.getMessage(this.getClass(),
"DataContentViewerHex.goToPageTextField.err"),
JOptionPane.WARNING_MESSAGE);
NbBundle.getMessage(this.getClass(),
"DataContentViewerHex.goToPageTextField.msgDlg",
totalPages),
NbBundle.getMessage(this.getClass(),
"DataContentViewerHex.goToPageTextField.err"),
JOptionPane.WARNING_MESSAGE);
return;
}
setDataViewByPageNumber(pageNumber);
}//GEN-LAST:event_goToPageTextFieldActionPerformed
/***
/**
* *
* Calculates the offset relative to the current caret position.
*
* @param userInput the user provided signed offset value.
*
* @return returns the resultant offset value relative to the current caret
* position. -1L is returned if the resultant offset cannot be calculated.
* position. -1L is returned if the resultant offset cannot be
* calculated.
*/
private long getOffsetRelativeToCaretPosition(Long userInput) {
String userSelectedLine;
@ -359,7 +364,6 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
private javax.swing.JLabel totalPageLabel;
// End of variables declaration//GEN-END:variables
/**
* Sets the DataView (The tabbed panel) by page number
*
@ -377,6 +381,7 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
setDataView(offset);
goToOffsetTextField.setText(Long.toString(offset));
}
/**
* Sets the DataView (The tabbed panel) by offset
*
@ -448,20 +453,20 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
resetComponent();
return;
}
Content content = (selectedNode).getLookup().lookup(Content.class);
if (content == null) {
resetComponent();
return;
}
dataSource = content;
totalPages = 0;
if (dataSource.getSize() > 0) {
totalPages = Math.round((dataSource.getSize() - 1) / pageLength) + 1;
}
totalPageLabel.setText(Integer.toString(totalPages));
this.setDataViewByPageNumber(1);
}
@ -519,7 +524,7 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
if (content != null && content.getSize() > 0) {
return true;
}
return false;
}
@ -533,7 +538,9 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
return this;
}
/* Show the right click menu only if evt is the correct mouse event */
/*
* Show the right click menu only if evt is the correct mouse event
*/
private void maybeShowPopup(java.awt.event.MouseEvent evt) {
if (evt.isPopupTrigger()) {
rightClickMenu.setLocation(evt.getLocationOnScreen());

View File

@ -288,12 +288,12 @@ public class DataContentViewerString extends javax.swing.JPanel implements DataC
}
if (pageNumber > maxPage || pageNumber < 1) {
JOptionPane.showMessageDialog(this,
NbBundle.getMessage(this.getClass(),
"DataContentViewerString.goToPageTextField.msgDlg",
maxPage),
NbBundle.getMessage(this.getClass(),
"DataContentViewerString.goToPageTextField.err"),
JOptionPane.WARNING_MESSAGE);
NbBundle.getMessage(this.getClass(),
"DataContentViewerString.goToPageTextField.msgDlg",
maxPage),
NbBundle.getMessage(this.getClass(),
"DataContentViewerString.goToPageTextField.err"),
JOptionPane.WARNING_MESSAGE);
return;
}
currentOffset = (pageNumber - 1) * pageLength;
@ -328,18 +328,17 @@ public class DataContentViewerString extends javax.swing.JPanel implements DataC
private javax.swing.JLabel totalPageLabel;
// End of variables declaration//GEN-END:variables
/**
* Sets the DataView (The tabbed panel)
*
* @param dataSource the content that want to be shown
* @param offset the starting offset
* @param offset the starting offset
*/
private void setDataView(Content dataSource, long offset) {
if (dataSource == null) {
return;
}
// change the cursor to "waiting cursor" for this operation
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
@ -353,8 +352,8 @@ public class DataContentViewerString extends javax.swing.JPanel implements DataC
bytesRead = dataSource.read(data, offset, pageLength); // read the data
} catch (TskException ex) {
text = NbBundle.getMessage(this.getClass(),
"DataContentViewerString.setDataView.errorText", currentOffset,
currentOffset + pageLength);
"DataContentViewerString.setDataView.errorText", currentOffset,
currentOffset + pageLength);
logger.log(Level.WARNING, "Error while trying to show the String content.", ex); //NON-NLS
}
}
@ -367,12 +366,12 @@ public class DataContentViewerString extends javax.swing.JPanel implements DataC
text = res.getText();
if (text.trim().isEmpty()) {
text = NbBundle.getMessage(this.getClass(),
"DataContentViewerString.setDataView.errorNoText", currentOffset,
currentOffset + pageLength);
"DataContentViewerString.setDataView.errorNoText", currentOffset,
currentOffset + pageLength);
}
} else {
text = NbBundle.getMessage(this.getClass(), "DataContentViewerString.setDataView.errorText", currentOffset,
currentOffset + pageLength);
currentOffset + pageLength);
}
// disable or enable the next button
@ -389,7 +388,6 @@ public class DataContentViewerString extends javax.swing.JPanel implements DataC
prevPageButton.setEnabled(true);
}
int totalPage = Math.round((dataSource.getSize() - 1) / pageLength) + 1;
totalPageLabel.setText(Integer.toString(totalPage));
currentPageLabel.setText(Integer.toString(currentPage));
@ -399,7 +397,7 @@ public class DataContentViewerString extends javax.swing.JPanel implements DataC
this.setCursor(null);
}
private void setDataView(StringContent dataSource) {
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
try {
@ -518,7 +516,9 @@ public class DataContentViewerString extends javax.swing.JPanel implements DataC
}
/* Show the right click menu only if evt is the correct mouse event */
/*
* Show the right click menu only if evt is the correct mouse event
*/
private void maybeShowPopup(java.awt.event.MouseEvent evt) {
if (evt.isPopupTrigger()) {
rightClickMenu.setLocation(evt.getLocationOnScreen());

View File

@ -48,17 +48,17 @@ import org.sleuthkit.autopsy.coreutils.Logger;
*
* The component is a generic JPanel and it can be reused in other swing
* components or in a TopComponent.
*
*
* Use the static factory methods to instantiate and customize the component.
* One option is to link a custom data content viewer to link to this viewer.
*
*
*/
public class DataResultPanel extends javax.swing.JPanel implements DataResult, ChangeListener {
private ExplorerManager explorerManager;
private Node rootNode;
private PropertyChangeSupport pcs;
// Different DataResultsViewers
private final List<UpdateWrapper> viewers = new ArrayList<>();
//custom content viewer to send selections to, or null if the main one
@ -66,21 +66,22 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
private boolean isMain;
private String title;
private final RootNodeListener rootNodeListener = new RootNodeListener();
private static final Logger logger = Logger.getLogger(DataResultPanel.class.getName() );
private static final Logger logger = Logger.getLogger(DataResultPanel.class.getName());
private boolean listeningToTabbedPane = false;
private static final String DUMMY_NODE_DISPLAY_NAME = NbBundle.getMessage(DataResultPanel.class,
"DataResultPanel.dummyNodeDisplayName");
"DataResultPanel.dummyNodeDisplayName");
/**
* Creates new DataResultPanel
* Default constructor, needed mostly for the palette/UI builder
* Use overrides or factory methods for more customization.
* Creates new DataResultPanel Default constructor, needed mostly for the
* palette/UI builder Use overrides or factory methods for more
* customization.
*/
private DataResultPanel() {
this.isMain = true;
pcs = new PropertyChangeSupport(this);
initComponents();
setName(title);
this.title = "";
@ -88,14 +89,14 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
/**
* Creates data result panel
*
* @param isMain whether it is the main panel associated with the main window,
* clients will almost always use false
* @param title title string to be displayed
*
* @param isMain whether it is the main panel associated with the main
* window, clients will almost always use false
* @param title title string to be displayed
*/
DataResultPanel(boolean isMain, String title) {
this();
setName(title);
this.isMain = isMain;
@ -106,26 +107,31 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
* Create a new, custom data result panel, in addition to the application
* main one and links with a custom data content panel.
*
* @param name unique name of the data result window, also used as title
* @param name unique name of the data result window, also
* used as title
* @param customContentViewer custom content viewer to send selection events
* to
* to
*/
DataResultPanel(String title, DataContent customContentViewer) {
this(false, title);
setName(title);
//custom content viewer tc to setup for every result viewer
this.customContentViewer = customContentViewer;
this.customContentViewer = customContentViewer;
}
/**
* Factory method to create, customize and open a new custom data result panel.
* Factory method to create, customize and open a new custom data result
* panel.
*
* @param title Title of the result panel
* @param pathText Descriptive text about the source of the nodes displayed
* @param givenNode The new root node
* @param title Title of the result panel
* @param pathText Descriptive text about the source of the nodes
* displayed
* @param givenNode The new root node
* @param totalMatches Cardinality of root node's children
* @return a new DataResultPanel instance representing a custom data result viewer
*
* @return a new DataResultPanel instance representing a custom data result
* viewer
*/
public static DataResultPanel createInstance(String title, String pathText, Node givenNode, int totalMatches) {
DataResultPanel newDataResult = new DataResultPanel(false, title);
@ -136,14 +142,18 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
}
/**
* Factory method to create, customize and open a new custom data result panel.
* Factory method to create, customize and open a new custom data result
* panel.
*
* @param title Title of the component window
* @param pathText Descriptive text about the source of the nodes displayed
* @param givenNode The new root node
* @param title Title of the component window
* @param pathText Descriptive text about the source of the nodes
* displayed
* @param givenNode The new root node
* @param totalMatches Cardinality of root node's children
* @param dataContent a handle to data content to send selection events to
* @return a new DataResultPanel instance representing a custom data result viewer
* @param dataContent a handle to data content to send selection events to
*
* @return a new DataResultPanel instance representing a custom data result
* viewer
*/
public static DataResultPanel createInstance(String title, String pathText, Node givenNode, int totalMatches, DataContent dataContent) {
DataResultPanel newDataResult = new DataResultPanel(title, dataContent);
@ -153,17 +163,20 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
return newDataResult;
}
/**
* Factory method to create, customize and open a new custom data result panel.
* Does NOT call open(). Client must manually initialize by calling open().
* Factory method to create, customize and open a new custom data result
* panel. Does NOT call open(). Client must manually initialize by calling
* open().
*
* @param title Title of the component window
* @param pathText Descriptive text about the source of the nodes displayed
* @param givenNode The new root node
* @param title Title of the component window
* @param pathText Descriptive text about the source of the nodes
* displayed
* @param givenNode The new root node
* @param totalMatches Cardinality of root node's children
* @param dataContent a handle to data content to send selection events to
* @return a new DataResultPanel instance representing a custom data result viewer
* @param dataContent a handle to data content to send selection events to
*
* @return a new DataResultPanel instance representing a custom data result
* viewer
*/
public static DataResultPanel createInstanceUninitialized(String title, String pathText, Node givenNode, int totalMatches, DataContent dataContent) {
DataResultPanel newDataResult = new DataResultPanel(title, dataContent);
@ -171,14 +184,14 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
createInstanceCommon(pathText, givenNode, totalMatches, newDataResult);
return newDataResult;
}
/**
* Common code for factory helper methods
*
* @param pathText
* @param givenNode
* @param totalMatches
* @param newDataResult
* @param newDataResult
*/
private static void createInstanceCommon(String pathText, Node givenNode, int totalMatches, DataResultPanel newDataResult) {
newDataResult.numberMatchLabel.setText(Integer.toString(totalMatches));
@ -189,18 +202,19 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
}
/**
* Sets content viewer to the custom one.
* Needs to be done before the first call to open()
* @param customContentViewer
* Sets content viewer to the custom one. Needs to be done before the first
* call to open()
*
* @param customContentViewer
*/
public void setContentViewer(DataContent customContentViewer) {
this.customContentViewer = customContentViewer;
}
/**
* Initializes the panel internals and activates it.
* Call it within your top component when it is opened.
* Do not use if used one of the factory methods to create and open the component.
* Initializes the panel internals and activates it. Call it within your top
* component when it is opened. Do not use if used one of the factory
* methods to create and open the component.
*/
public void open() {
if (null == explorerManager) {
@ -220,7 +234,7 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
// and is the parent of a DataContentPanel that hosts a set of DataContentViewers.
explorerManager.addPropertyChangeListener(new ExplorerManagerNodeSelectionListener());
}
// Add all the DataContentViewer to the tabbed pannel.
// (Only when the it's opened at the first time: tabCount = 0)
int totalTabs = this.dataResultTabbedPanel.getTabCount();
@ -229,9 +243,9 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
// as DataResultViewer service providers when DataResultViewers are updated
// to better handle the ExplorerManager sharing implemented to support actions that operate on
// multiple selected nodes.
addDataResultViewer(new DataResultViewerTable(this.explorerManager));
addDataResultViewer(new DataResultViewerTable(this.explorerManager));
addDataResultViewer(new DataResultViewerThumbnail(this.explorerManager));
// Find all DataResultViewer service providers and add them to the tabbed pane.
for (DataResultViewer factory : Lookup.getDefault().lookupAll(DataResultViewer.class)) {
// @@@ Revist this isMain condition, it may be obsolete. If not,
@ -240,9 +254,8 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
DataResultViewer drv;
if (isMain) {
//for main window, use the instance in the lookup
drv = factory;
}
else {
drv = factory;
} else {
//create a new instance of the viewer for non-main window
drv = factory.createInstance();
}
@ -259,8 +272,9 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
this.setVisible(true);
}
private class ExplorerManagerNodeSelectionListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (!Case.isCaseOpen()) {
@ -271,7 +285,7 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
if (evt.getPropertyName().equals(ExplorerManager.PROP_SELECTED_NODES)) {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
// If a custom DataContent object has not been specified, get the default instance.
DataContent contentViewer = customContentViewer;
if (contentViewer == null) {
@ -279,19 +293,18 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
}
try {
if (contentViewer != null) {
if (contentViewer != null) {
Node[] selectedNodes = explorerManager.getSelectedNodes();
for (UpdateWrapper drv : viewers) {
drv.setSelectedNodes(selectedNodes);
}
}
// Passing null signals that either multiple nodes are selected, or no nodes are selected.
// This is important to the DataContent object, since the content mode (area) of the app is designed
// to show only the content underlying a single Node.
if (selectedNodes.length == 1) {
contentViewer.setNode(selectedNodes[0]);
}
else {
} else {
contentViewer.setNode(null);
}
}
@ -301,20 +314,20 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
}
}
}
private void addDataResultViewer(DataResultViewer dataResultViewer) {
UpdateWrapper viewerWrapper = new UpdateWrapper(dataResultViewer);
if (null != this.customContentViewer) {
viewerWrapper.setContentViewer(this.customContentViewer);
}
this.viewers.add(viewerWrapper);
this.dataResultTabbedPanel.addTab(dataResultViewer.getTitle(), dataResultViewer.getComponent());
this.dataResultTabbedPanel.addTab(dataResultViewer.getTitle(), dataResultViewer.getComponent());
}
/**
* Tears down the component.
* Use within your outer container (such as a top component) when it goes away to tear
* down this component and detach its listeners.
* Tears down the component. Use within your outer container (such as a top
* component) when it goes away to tear down this component and detach its
* listeners.
*/
void close() {
// try to remove any references to this class
@ -349,9 +362,8 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
if (pcs == null) {
logger.log(Level.WARNING, "Could not add listener to DataResultPanel, " //NON-NLS
+ "listener support not fully initialized yet, listener: " + listener.toString() ); //NON-NLS
}
else {
+ "listener support not fully initialized yet, listener: " + listener.toString()); //NON-NLS
} else {
this.pcs.addPropertyChangeListener(listener);
}
}
@ -374,26 +386,26 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
// Deferring becoming a listener to the tabbed pane until this point
// eliminates handling a superfluous stateChanged event during construction.
if (listeningToTabbedPane == false) {
dataResultTabbedPanel.addChangeListener(this);
dataResultTabbedPanel.addChangeListener(this);
listeningToTabbedPane = true;
}
this.rootNode = selectedNode;
if (this.rootNode != null) {
rootNodeListener.reset();
this.rootNode.addNodeListener(rootNodeListener);
}
resetTabs(selectedNode);
setupTabs(selectedNode);
if (selectedNode != null) {
int childrenCount = selectedNode.getChildren().getNodesCount();
this.numberMatchLabel.setText(Integer.toString(childrenCount));
}
this.numberMatchLabel.setVisible(true);
}
private void setupTabs(Node selectedNode) {
//update/disable tabs based on if supported for this node
int drvC = 0;
@ -433,7 +445,7 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
@Override
public void setTitle(String title) {
setName(title);
}
@Override
@ -452,10 +464,10 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
for (UpdateWrapper w : viewers) {
ret.add(w.getViewer());
}
return ret;
}
public boolean canClose() {
return (!this.isMain) || !Case.existsCurrentCase() || Case.getCurrentCase().hasData() == false; // only allow this window to be closed when there's no case opened or no image in this case
}
@ -472,22 +484,22 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
// to better handle the ExplorerManager sharing implemented to support actions that operate on
// multiple selected nodes.
//if (drv.isOutdated()) {
// change the cursor to "waiting cursor" for this operation
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
try {
drv.setNode(rootNode);
} finally {
this.setCursor(null);
}
// change the cursor to "waiting cursor" for this operation
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
try {
drv.setNode(rootNode);
} finally {
this.setCursor(null);
}
//}
}
}
/**
* why does this take a Node as parameter and then ignore it?
*
*
*
*
*
*
* Resets the tabs based on the selected Node. If the selected node is null
* or not supported, disable that tab as well.
*
@ -573,7 +585,7 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
this.wrapped = wrapped;
this.outdated = true;
}
DataResultViewer getViewer() {
return wrapped;
}
@ -612,6 +624,7 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
/**
* Set number of matches to be displayed in the top right
*
* @param numMatches
*/
public void setNumMatches(Integer numMatches) {
@ -619,7 +632,7 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
this.numberMatchLabel.setText(Integer.toString(numMatches));
}
}
private class RootNodeListener implements NodeListener {
private volatile boolean waitingForData = true;
@ -632,12 +645,13 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
public void childrenAdded(final NodeMemberEvent nme) {
Node[] delta = nme.getDelta();
updateMatches();
/* There is a known issue in this code whereby we will only
call setupTabs() once even though childrenAdded could be
called multiple times. That means that each panel may not
have access to all of the children when they decide if they
support the content */
/*
* There is a known issue in this code whereby we will only call
* setupTabs() once even though childrenAdded could be called
* multiple times. That means that each panel may not have access to
* all of the children when they decide if they support the content
*/
if (waitingForData && containsReal(delta)) {
waitingForData = false;
if (SwingUtilities.isEventDispatchThread()) {
@ -652,7 +666,7 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
}
}
}
private boolean containsReal(Node[] delta) {
for (Node n : delta) {
if (!n.getDisplayName().equals(DUMMY_NODE_DISPLAY_NAME)) {
@ -661,13 +675,13 @@ public class DataResultPanel extends javax.swing.JPanel implements DataResult, C
}
return false;
}
/**
* Updates the Number of Matches label on the DataResultPanel.
*
*
*/
private void updateMatches() {
if (rootNode != null && rootNode.getChildren() != null) {
if (rootNode != null && rootNode.getChildren() != null) {
setNumMatches(rootNode.getChildren().getNodesCount());
}
}

View File

@ -36,20 +36,22 @@ import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Top component which displays results (top-right editor mode by default).
*
*
* There is a main tc instance that responds to directory tree selections.
* Others can also create an additional result viewer tc using one of the factory methods, that can be:
*
* - added to top-right corner as an additional, closeable viewer
* - added to a different, custom mode,
* - linked to a custom content viewer that responds to selections from this top component.
*
* For embedding custom data result in other top components window, use DataResultPanel component instead,
* since we cannot nest top components.
*
* Others can also create an additional result viewer tc using one of the
* factory methods, that can be:
*
* - added to top-right corner as an additional, closeable viewer - added to a
* different, custom mode, - linked to a custom content viewer that responds to
* selections from this top component.
*
* For embedding custom data result in other top components window, use
* DataResultPanel component instead, since we cannot nest top components.
*
* Encapsulates the internal DataResultPanel and delegates to it.
*
* Implements DataResult interface by delegating to the encapsulated DataResultPanel.
*
* Implements DataResult interface by delegating to the encapsulated
* DataResultPanel.
*/
public class DataResultTopComponent extends TopComponent implements DataResult, ExplorerManager.Provider {
@ -58,7 +60,7 @@ public class DataResultTopComponent extends TopComponent implements DataResult,
private DataResultPanel dataResultPanel; //embedded component with all the logic
private boolean isMain;
private String customModeName;
//keep track of tcs opened for menu presenters
private static final List<String> activeComponentIds = Collections.synchronizedList(new ArrayList<String>());
@ -66,8 +68,8 @@ public class DataResultTopComponent extends TopComponent implements DataResult,
* Create a new data result top component
*
* @param isMain whether it is the main, application default result viewer,
* there can be only 1 main result viewer
* @param title title of the data result window
* there can be only 1 main result viewer
* @param title title of the data result window
*/
public DataResultTopComponent(boolean isMain, String title) {
associateLookup(ExplorerUtils.createLookup(explorerManager, getActionMap()));
@ -80,19 +82,20 @@ public class DataResultTopComponent extends TopComponent implements DataResult,
* Create a new, custom data result top component, in addition to the
* application main one
*
* @param name unique name of the data result window, also used as title
* @param customModeName custom mode to dock into
* @param name unique name of the data result window, also
* used as title
* @param customModeName custom mode to dock into
* @param customContentViewer custom content viewer to send selection events
* to
* to
*/
DataResultTopComponent(String name, String mode, DataContentTopComponent customContentViewer) {
associateLookup(ExplorerUtils.createLookup(explorerManager, getActionMap()));
this.customModeName = mode;
dataResultPanel = new DataResultPanel(name, customContentViewer);
initComponents();
customizeComponent(isMain, name);
customizeComponent(isMain, name);
}
private void customizeComponent(boolean isMain, String title) {
this.isMain = isMain;
this.customModeName = null;
@ -111,10 +114,12 @@ public class DataResultTopComponent extends TopComponent implements DataResult,
/**
* Initialize previously created tc instance with additional data
*
* @param pathText
* @param givenNode
* @param totalMatches
* @param newDataResult previously created with createInstance() uninitialized instance
* @param newDataResult previously created with createInstance()
* uninitialized instance
*/
public static void initInstance(String pathText, Node givenNode, int totalMatches, DataResultTopComponent newDataResult) {
newDataResult.setNumMatches(totalMatches);
@ -124,17 +129,19 @@ public class DataResultTopComponent extends TopComponent implements DataResult,
// set the tree table view
newDataResult.setNode(givenNode);
newDataResult.setPath(pathText);
newDataResult.requestActive();
}
/**
* Creates a new non-default DataResult component and initializes it
*
* @param title Title of the component window
* @param pathText Descriptive text about the source of the nodes displayed
* @param givenNode The new root node
* @param title Title of the component window
* @param pathText Descriptive text about the source of the nodes
* displayed
* @param givenNode The new root node
* @param totalMatches Cardinality of root node's children
*
* @return a new, not default, initialized DataResultTopComponent instance
*/
public static DataResultTopComponent createInstance(String title, String pathText, Node givenNode, int totalMatches) {
@ -146,16 +153,19 @@ public class DataResultTopComponent extends TopComponent implements DataResult,
}
/**
* Creates a new non-default DataResult component linked with a custom data content, and initializes it.
*
* Creates a new non-default DataResult component linked with a custom data
* content, and initializes it.
*
* @param title Title of the component window
* @param mode custom mode to dock this custom TopComponent to
* @param pathText Descriptive text about the source of the nodes displayed
* @param givenNode The new root node
* @param totalMatches Cardinality of root node's children
*
* @param title Title of the component window
* @param mode custom mode to dock this custom TopComponent to
* @param pathText Descriptive text about the source of the nodes
* displayed
* @param givenNode The new root node
* @param totalMatches Cardinality of root node's children
* @param dataContentWindow a handle to data content top component window to
* @return a new, not default, initialized DataResultTopComponent instance
*
* @return a new, not default, initialized DataResultTopComponent instance
*/
public static DataResultTopComponent createInstance(String title, final String mode, String pathText, Node givenNode, int totalMatches, DataContentTopComponent dataContentWindow) {
DataResultTopComponent newDataResult = new DataResultTopComponent(title, mode, dataContentWindow);
@ -163,13 +173,15 @@ public class DataResultTopComponent extends TopComponent implements DataResult,
initInstance(pathText, givenNode, totalMatches, newDataResult);
return newDataResult;
}
/**
* Creates a new non-default DataResult component.
* You probably want to use initInstance after it
*
* Creates a new non-default DataResult component. You probably want to use
* initInstance after it
*
* @param title
* @return a new, not default, not fully initialized DataResultTopComponent instance
*
* @return a new, not default, not fully initialized DataResultTopComponent
* instance
*/
public static DataResultTopComponent createInstance(String title) {
final DataResultTopComponent newDataResult = new DataResultTopComponent(false, title);
@ -181,15 +193,16 @@ public class DataResultTopComponent extends TopComponent implements DataResult,
public ExplorerManager getExplorerManager() {
return explorerManager;
}
/**
* Get a list with names of active windows ids, e.g. for the menus
* @return
*
* @return
*/
public static List<String> getActiveComponentIds() {
return new ArrayList<>(activeComponentIds);
}
/**
* 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
@ -233,7 +246,7 @@ public class DataResultTopComponent extends TopComponent implements DataResult,
public List<DataResultViewer> getViewers() {
return dataResultPanel.getViewers();
}
private void setCustomMode() {
if (customModeName != null) {
//putClientProperty("TopComponentAllowDockAnywhere", Boolean.TRUE);
@ -256,14 +269,14 @@ public class DataResultTopComponent extends TopComponent implements DataResult,
@Override
public void componentOpened() {
super.componentOpened();
this.dataResultPanel.open();
this.dataResultPanel.open();
}
@Override
public void componentClosed() {
super.componentClosed();
activeComponentIds.remove(this.getName());
dataResultPanel.close();
dataResultPanel.close();
}
@Override

View File

@ -147,6 +147,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
* Gets regular Bean property set properties from first child of Node.
*
* @param parent Node with at least one child to get properties from
*
* @return Properties,
*/
private Node.Property<?>[] getChildPropertyHeaders(Node parent) {
@ -173,6 +174,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
* load - you need to set all children props for the parent by hand
*
* @param parent Node with at least one child to get properties from
*
* @return Properties,
*/
@SuppressWarnings("rawtypes")
@ -213,8 +215,8 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
* load - you need to set all children props for the parent by hand
*
* @param parent Node with at least one child to get properties from
* @param rows max number of rows to retrieve properties for (can be used
* for memory optimization)
* @param rows max number of rows to retrieve properties for (can be used
* for memory optimization)
*/
private void getAllChildPropertyHeadersRec(Node parent, int rows) {
Children children = parent.getChildren();
@ -296,7 +298,6 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
em.setRootContext(root);
final OutlineView ov = ((OutlineView) DataResultViewerTable.this.tableScrollPanel);
if (ov == null) {
@ -307,21 +308,23 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
DataResultViewerTable.this.getAllChildPropertyHeadersRec(root, 100);
List<Node.Property<?>> props = new ArrayList<>(propertiesAcc);
/* OutlineView makes the first column be the result of node.getDisplayName with the icon. This
* duplicates our first column, which is the file name, etc. So, pop that property off the list, but
* use its display name as the header for the column so that the header can change depending on the
* type of data being displayed.
/*
* OutlineView makes the first column be the result of
* node.getDisplayName with the icon. This duplicates our first column,
* which is the file name, etc. So, pop that property off the list, but
* use its display name as the header for the column so that the header
* can change depending on the type of data being displayed.
*
* NOTE: This assumes that the first property is always the one tha duplicates getDisplayName(). This
* seems like a big assumption and could be made more robust.
* NOTE: This assumes that the first property is always the one tha
* duplicates getDisplayName(). This seems like a big assumption and
* could be made more robust.
*/
if (props.size() > 0) {
Node.Property<?> prop = props.remove(0);
((DefaultOutlineModel) ov.getOutline().getOutlineModel()).setNodesColumnLabel(prop.getDisplayName());
}
// Get the columns setup with respect to names and sortability
String[] propStrings = new String[props.size() * 2];
for (int i = 0; i < props.size(); i++) {
@ -344,10 +347,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
// try {
// this.getExplorerManager().setSelectedNodes(new Node[]{firstEntryNode});
// } catch (PropertyVetoException ex) {}
// show the horizontal scroll panel and show all the content & header
int totalColumns = props.size();
//int scrollWidth = ttv.getWidth();
@ -358,13 +358,10 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
// Just let the table resize itself.
ov.getOutline().setAutoResizeMode((props.size() > 0) ? JTable.AUTO_RESIZE_OFF : JTable.AUTO_RESIZE_ALL_COLUMNS);
// get first 100 rows values for the table
Object[][] content = null;
content = getRowValues(root, 100);
if (content != null) {
// get the fontmetrics
final Graphics graphics = ov.getGraphics();
@ -438,12 +435,13 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
/**
* Gets the max width of the column from the given index, header, and table.
*
* @param index the index of the column on the table / header
* @param index the index of the column on the table / header
* @param metrics the font metrics that this component use
* @param margin the left/right margin of the column
* @param margin the left/right margin of the column
* @param padding the left/right padding of the column
* @param header the property headers of the table
* @param table the object table
* @param header the property headers of the table
* @param table the object table
*
* @return max the maximum width of the column
*/
@SuppressWarnings("rawtypes")
@ -457,12 +455,13 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
/**
* Gets the max width of the column from the given index, header, and table.
*
* @param index the index of the column on the table / header
* @param index the index of the column on the table / header
* @param metrics the font metrics that this component use
* @param margin the left/right margin of the column
* @param margin the left/right margin of the column
* @param padding the left/right padding of the column
* @param header the column header for the comparison
* @param table the object table
* @param header the column header for the comparison
* @param table the object table
*
* @return max the maximum width of the column
*/
private synchronized int getMaxColumnWidth(int index, FontMetrics metrics, int margin, int padding, String header, Object[][] table) {

View File

@ -201,13 +201,19 @@ public class FXVideoPanel extends MediaViewVideoPanel {
private final MediaView mediaView;
/** The Duration of the media. * */
/**
* The Duration of the media. *
*/
private Duration duration;
/** The container for the media controls. * */
/**
* The container for the media controls. *
*/
private final HBox mediaTools;
/** The container for the media video output. * */
/**
* The container for the media video output. *
*/
private final HBox mediaViewPane;
private final VBox controlPanel;
@ -629,9 +635,10 @@ public class FXVideoPanel extends MediaViewVideoPanel {
/**
* @param file a video file from which to capture frames
* @param numFrames the number of frames to capture. These frames will be
* captured at successive intervals given by durationOfVideo/numFrames. If
* this frame interval is less than MIN_FRAME_INTERVAL_MILLIS, then only one
* frame will be captured and returned.
* captured at successive intervals given by
* durationOfVideo/numFrames. If this frame interval is
* less than MIN_FRAME_INTERVAL_MILLIS, then only one frame
* will be captured and returned.
*
* @return a List of VideoFrames representing the captured frames.
*/

View File

@ -24,13 +24,15 @@ import java.util.List;
/**
* Interface used to capture frames from a video file.
*/
public interface FrameCapture {
public interface FrameCapture {
/**
* @param file the video file to use
* @param file the video file to use
* @param numFrames the number of frames to capture. Note that the actual
* number of frames returned may be less than this number. Specifically, this
* may happen if the video is very short.
* number of frames returned may be less than this number.
* Specifically, this may happen if the video is very
* short.
*
* @return a list of VideoFrames representing the captured frames
*/
List<VideoFrame> captureFrames(File file, int numFrames) throws Exception;

View File

@ -131,8 +131,8 @@ public class GstVideoPanel extends MediaViewVideoPanel {
progressSlider.addChangeListener((ChangeEvent e) -> {
/**
* Should always try to synchronize any call to
* progressSlider.setValue() to avoid a different thread
* changing playbin while stateChanged() is processing
* progressSlider.setValue() to avoid a different thread changing
* playbin while stateChanged() is processing
*/
int time = progressSlider.getValue();
synchronized (playbinLock) {
@ -276,9 +276,10 @@ public class GstVideoPanel extends MediaViewVideoPanel {
/**
* @param file a video file from which to capture frames
* @param numFrames the number of frames to capture. These frames will be
* captured at successive intervals given by durationOfVideo/numFrames. If
* this frame interval is less than MIN_FRAME_INTERVAL_MILLIS, then only one
* frame will be captured and returned.
* captured at successive intervals given by
* durationOfVideo/numFrames. If this frame interval is
* less than MIN_FRAME_INTERVAL_MILLIS, then only one frame
* will be captured and returned.
*
* @return a List of VideoFrames representing the captured frames.
*/
@ -590,9 +591,9 @@ public class GstVideoPanel extends MediaViewVideoPanel {
/**
* @return true while millisElapsed is greater than END_TIME_MARGIN_MS
* from durationMillis. This is used to indicate when the video has
* ended because for some videos the time elapsed never becomes equal to
* the reported duration of the video.
* from durationMillis. This is used to indicate when the video
* has ended because for some videos the time elapsed never
* becomes equal to the reported duration of the video.
*/
private boolean hasNotEnded() {
return (durationMillis - millisElapsed) > END_TIME_MARGIN_MS;
@ -659,7 +660,9 @@ public class GstVideoPanel extends MediaViewVideoPanel {
}
} //end class progress worker
/* Thread that extracts and plays a file */
/*
* Thread that extracts and plays a file
*/
private class ExtractMedia extends SwingWorker<Long, Void> {
private ProgressHandle progress;
@ -687,7 +690,9 @@ public class GstVideoPanel extends MediaViewVideoPanel {
return 0L;
}
/* clean up or start the worker threads */
/*
* clean up or start the worker threads
*/
@Override
protected void done() {
try {

View File

@ -66,7 +66,9 @@ public class Installer extends ModuleInstall {
UIManager.put(DefaultTabbedContainerUI.KEY_VIEW_CONTENT_BORDER, BorderFactory.createEmptyBorder());
UIManager.put("TabbedPane.contentBorderInsets", new Insets(0, 0, 0, 0));
/* Open the passed in case, if an aut file was double clicked. */
/*
* Open the passed in case, if an aut file was double clicked.
*/
WindowManager.getDefault().invokeWhenUIReady(new Runnable() {
@Override
public void run() {
@ -88,7 +90,6 @@ public class Installer extends ModuleInstall {
}
});
}
@Override
@ -100,50 +101,48 @@ public class Installer extends ModuleInstall {
@Override
public void close() {
try {
if (Case.isCaseOpen())
if (Case.isCaseOpen()) {
Case.getCurrentCase().closeCase();
}
catch (CaseActionException ex) {
}
} catch (CaseActionException ex) {
logger.log(Level.WARNING, "Error closing case. ", ex); //NON-NLS
}
}
private void setupLAF() {
//TODO apply custom skinning
//UIManager.put("nimbusBase", new Color());
//UIManager.put("nimbusBlueGrey", new Color());
//UIManager.put("control", new Color());
if (System.getProperty("os.name").toLowerCase().contains("mac")) { //NON-NLS
setupMacOsXLAF();
}
}
/**
* Set the look and feel to be the Cross Platform 'Metal', but keep Aqua
* dependent elements that set the Menu Bar to be in the correct place on
* Set the look and feel to be the Cross Platform 'Metal', but keep Aqua
* dependent elements that set the Menu Bar to be in the correct place on
* Mac OS X.
*/
private void setupMacOsXLAF() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException | UnsupportedLookAndFeelException ex) {
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
logger.log(Level.WARNING, "Unable to set theme. ", ex); //NON-NLS
}
final String[] UI_MENU_ITEM_KEYS = new String[]{"MenuBarUI", //NON-NLS
};
};
Map<Object, Object> uiEntries = new TreeMap<>();
// Store the keys that deal with menu items
for(String key : UI_MENU_ITEM_KEYS) {
for (String key : UI_MENU_ITEM_KEYS) {
uiEntries.put(key, UIManager.get(key));
}
//use Metal if available
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) { //NON-NLS
@ -158,7 +157,7 @@ public class Installer extends ModuleInstall {
}
// Overwrite the Metal menu item keys to use the Aqua versions
for (Map.Entry<Object,Object> entry : uiEntries.entrySet()) {
for (Map.Entry<Object, Object> entry : uiEntries.entrySet()) {
UIManager.put(entry.getKey(), entry.getValue());
}
}

View File

@ -151,8 +151,10 @@ public class MediaViewImagePanel extends JPanel implements DataContentViewerMedi
@Override
public void run() {
if (!Case.isCaseOpen()) {
/* handle in-between condition when case is being closed
* and an image was previously selected */
/*
* handle in-between condition when case is being closed and
* an image was previously selected
*/
return;
}
try (InputStream inputStream = new BufferedInputStream(new ReadContentInputStream(file));) {

View File

@ -33,8 +33,8 @@ import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.TskCoreException;
/**
* Video viewer part of the Media View layered pane.
* Uses different engines depending on platform.
* Video viewer part of the Media View layered pane. Uses different engines
* depending on platform.
*/
public abstract class MediaViewVideoPanel extends JPanel implements FrameCapture, DataContentViewerMedia.MediaViewPanel {

View File

@ -34,71 +34,74 @@ import org.netbeans.swing.tabcontrol.TabDisplayerUI;
* @author dfickling
*/
public class NoTabsTabDisplayerUI extends TabDisplayerUI {
/** Creates a new instance of NoTabsTabDisplayerUI */
/**
* Creates a new instance of NoTabsTabDisplayerUI
*/
public NoTabsTabDisplayerUI(TabDisplayer displayer) {
super(displayer);
}
public static ComponentUI createUI(JComponent jc) {
assert jc instanceof TabDisplayer;
return new NoTabsTabDisplayerUI((TabDisplayer) jc);
}
private static final int[] PTS = new int[] { 0, 0, 0 };
private static final int[] PTS = new int[]{0, 0, 0};
public Polygon getExactTabIndication(int i) {
//Should never be called
return new Polygon(PTS, PTS, PTS.length);
}
public Polygon getInsertTabIndication(int i) {
return new Polygon(PTS, PTS, PTS.length);
}
public int tabForCoordinate(Point point) {
return -1;
}
public Rectangle getTabRect(int i, Rectangle rectangle) {
return new Rectangle(0,0,0,0);
return new Rectangle(0, 0, 0, 0);
}
protected SingleSelectionModel createSelectionModel() {
return new DefaultSingleSelectionModel();
}
public java.lang.String getCommandAtPoint(Point point) {
return null;
}
public int dropIndexOfPoint(Point point) {
return -1;
}
public void registerShortcuts(javax.swing.JComponent jComponent) {
//do nothing
}
public void unregisterShortcuts(javax.swing.JComponent jComponent) {
//do nothing
}
protected void requestAttention(int i) {
//do nothing
}
protected void cancelRequestAttention(int i) {
//do nothing
}
public Dimension getPreferredSize(javax.swing.JComponent c) {
return new Dimension(0, 0);
}
public Dimension getMinimumSize(javax.swing.JComponent c) {
return new Dimension(0, 0);
}
public Dimension getMaximumSize(javax.swing.JComponent c) {
return new Dimension(0, 0);
}

View File

@ -53,8 +53,8 @@ import java.util.logging.Logger;
public final class OfflineHelpAction implements ActionListener {
private URI uri;
private static final Logger Logger =
org.sleuthkit.autopsy.coreutils.Logger.getLogger(AboutWindowPanel.class.getName());
private static final Logger Logger
= org.sleuthkit.autopsy.coreutils.Logger.getLogger(AboutWindowPanel.class.getName());
@Override
public void actionPerformed(ActionEvent e) {
@ -65,8 +65,7 @@ public final class OfflineHelpAction implements ActionListener {
* Displays the Offline Documentation in the system browser. If not
* available, displays it in the built-in OpenIDE HTML Browser.
*
* Tested and working: Chrome, Firefox, IE
* Not tested: Opera, Safari
* Tested and working: Chrome, Firefox, IE Not tested: Opera, Safari
*/
private void viewOfflineHelp() {
String fileForHelp = "";

View File

@ -8,16 +8,16 @@ package org.sleuthkit.autopsy.corecomponents;
*
*/
public interface OptionsPanel {
/**
* Store the current state of all options in this OptionsPanel.
*/
public void store();
/**
* Load the saved state of all options, and refresh this
* OptionsPanel accordingly.
* Load the saved state of all options, and refresh this OptionsPanel
* accordingly.
*/
public void load();
}

View File

@ -27,7 +27,9 @@ import org.openide.nodes.Node;
*/
class TableFilterChildren extends FilterNode.Children {
/** the constructor */
/**
* the constructor
*/
TableFilterChildren(Node arg) {
super(arg);
}
@ -47,6 +49,7 @@ class TableFilterChildren extends FilterNode.Children {
* Converts the given FsContent into "Children".
*
* @param fs
*
* @return children
*/
public static Children createInstance(Node arg, boolean createChild) {
@ -56,4 +59,4 @@ class TableFilterChildren extends FilterNode.Children {
return Children.LEAF;
}
}
}
}

View File

@ -23,8 +23,9 @@ import org.openide.nodes.Node;
import org.openide.util.NbBundle;
/**
* This class is used to filter the nodes that we want to show on the "TreeTableView".
* So basically we just want to show one layer of nodes from it's parent.
* This class is used to filter the nodes that we want to show on the
* "TreeTableView". So basically we just want to show one layer of nodes from
* it's parent.
*
* @author jantonius
*/
@ -32,7 +33,9 @@ public class TableFilterNode extends FilterNode {
private boolean createChild;
/** the constructor */
/**
* the constructor
*/
public TableFilterNode(Node arg, boolean crChild) {
super(arg, TableFilterChildren.createInstance(arg, crChild));
this.createChild = crChild;
@ -42,7 +45,7 @@ public class TableFilterNode extends FilterNode {
* Override the display name / header for the first (tree) column on the
* "TreeTableView".
*
* @return disName the display name for the first column
* @return disName the display name for the first column
*/
@Override
public String getDisplayName() {

View File

@ -59,7 +59,6 @@ class ThumbnailViewChildren extends Children.Keys<Integer> {
this.iconSize = iconSize;
}
@Override
protected void addNotify() {
super.addNotify();

View File

@ -9,7 +9,7 @@ public class VideoFrame {
private Image frame;
private long timeMillis;
public VideoFrame(Image frame, long timeMillis) {
this.frame = frame;
this.timeMillis = timeMillis;

View File

@ -16,7 +16,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.coreutils;
import java.awt.Component;
@ -42,20 +41,19 @@ public class AutopsyExceptionHandler extends Handler {
static final Handler nbErrorManager = new NbErrorManager(); // Default NetBeans handler
static final Version.Type buildType = Version.getBuildType();
private final Logger logger = Logger.getLogger(AutopsyExceptionHandler.class.getName());
public AutopsyExceptionHandler() {
super();
this.setLevel(Level.SEVERE);
/*
if (buildType == Version.Type.DEVELOPMENT)
//for dev builds, show dialogs for WARNING and above
this.setLevel(Level.WARNING);
else
//for production builds, show dialogs for SEVERE and above (TODO in future consider not show any, explicit dialogs should be in place)
this.setLevel(Level.SEVERE);
*/
* if (buildType == Version.Type.DEVELOPMENT) //for dev builds, show
* dialogs for WARNING and above this.setLevel(Level.WARNING); else
* //for production builds, show dialogs for SEVERE and above (TODO in
* future consider not show any, explicit dialogs should be in place)
* this.setLevel(Level.SEVERE);
*/
this.setFilter(new ExceptionFilter());
this.setFormatter(new SimpleFormatter());
}
@ -69,7 +67,7 @@ public class AutopsyExceptionHandler extends Handler {
// Throwable was anticipated, caught and logged. Display log message and throwable message.
final int levelValue = record.getLevel().intValue();
final Component parentComponent = null; // Use default window frame.
final String message = formatExplanation(record);
final String title = getTitleForLevelValue(levelValue);
@ -78,19 +76,19 @@ public class AutopsyExceptionHandler extends Handler {
// publish() was probably not called from the EDT, so run the message box there instead of here.
//only show the dialog in dev builds
if (buildType == Version.Type.DEVELOPMENT) {
SwingUtilities.invokeLater(new Runnable() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JOptionPane.showMessageDialog(
parentComponent,
message,
title,
messageType);
}
});
@Override
public void run() {
JOptionPane.showMessageDialog(
parentComponent,
message,
title,
messageType);
}
});
}
logger.log(Level.SEVERE, "Unexpected error: " + title + ", " + message ); //NON-NLS
logger.log(Level.SEVERE, "Unexpected error: " + title + ", " + message); //NON-NLS
} else {
// Throwable (unanticipated) error. Use built-in exception handler to offer details, stacktrace.
nbErrorManager.publish(record);
@ -98,11 +96,11 @@ public class AutopsyExceptionHandler extends Handler {
}
}
/**
* Filter only accepts records with exceptions attached.
*/
private static class ExceptionFilter implements Filter {
@Override
public boolean isLoggable(LogRecord record) {
// True if there is an uncaught exception being thrown.
@ -112,8 +110,11 @@ public class AutopsyExceptionHandler extends Handler {
/**
*
* @param record A LogRecord with both a message and associated Throwable set.
* @return A String containing the log message and the cause of the Throwable (if there is one).
* @param record A LogRecord with both a message and associated Throwable
* set.
*
* @return A String containing the log message and the cause of the
* Throwable (if there is one).
*/
private String formatExplanation(LogRecord record) {
final String logMessage = getFormatter().formatMessage(record);
@ -136,7 +137,6 @@ public class AutopsyExceptionHandler extends Handler {
// return explanation + recursiveExplanation(cause);
// }
// }
private static int getMessageTypeForLevelValue(int levelValue) {
if (levelValue >= SEVERE_VALUE) {
return JOptionPane.ERROR_MESSAGE;

View File

@ -29,9 +29,11 @@ import org.sleuthkit.autopsy.corecomponentinterfaces.ContextMenuActionsProvider;
* This class implements the ContextMenuActionsProvider extension point.
*/
public class ContextMenuExtensionPoint {
/**
* Gets all of the Actions provided by registered implementers of the
* Gets all of the Actions provided by registered implementers of the
* ContextMenuActionsProvider interface.
*
* @return A list, possibly empty, of Action objects.
*/
static public List<Action> getActions() {

View File

@ -22,6 +22,7 @@ package org.sleuthkit.autopsy.coreutils;
* Encapsulates an error message and an associated exception, if any.
*/
final public class ErrorInfo {
private final String errorSource;
private final String message;
private final Exception exception;
@ -41,7 +42,7 @@ final public class ErrorInfo {
public String getErrroSource() {
return this.errorSource;
}
public String getMessage() {
return this.message;
}
@ -49,7 +50,7 @@ final public class ErrorInfo {
public boolean hasException() {
return exception != null;
}
public Exception getException() {
return this.exception;
}

View File

@ -35,6 +35,7 @@ public class EscapeUtil {
* Decode the given url in UTF-8.
*
* @param url the url to be decoded
*
* @return the decoded URL
*/
public static String decodeURL(String url) {
@ -51,6 +52,7 @@ public class EscapeUtil {
* Encode the given url in UTF-8 to
*
* @param url the url to be decoded
*
* @return the encoded URL string
*/
public static String encodeURL(String url) {
@ -62,19 +64,23 @@ public class EscapeUtil {
return "";
}
}
/**
* Escape html
* Escape html
*
* @param toEscape text (with html tags) to escape
*
* @return html-escaped string
*/
public static String escapeHtml(String toEscape) {
return StringEscapeUtils.escapeHtml4(toEscape);
}
/**
* Unescape html
*
* @param toUnescape text (potentially escaped html) to unescape
*
* @return html unescaped string
*/
public static String unEscapeHtml(String toUnescape) {

View File

@ -61,12 +61,12 @@ public final class ExecUtil {
public static class TimedProcessTerminator implements ProcessTerminator {
private final long startTimeInSeconds;
private final long maxRunTimeInSeconds;
private final long maxRunTimeInSeconds;
/**
* Creates a process terminator that can be used to kill a process after
* it has run for a given period of time.
*
*
* @param maxRunTimeInSeconds The maximum allowable run time in seconds.
*/
public TimedProcessTerminator(long maxRunTimeInSeconds) {
@ -88,11 +88,13 @@ public final class ExecUtil {
* Runs a process without a timeout and terminator.
*
* @param processBuilder A process builder used to configure and construct
* the process to be run.
* the process to be run.
*
* @return the exit value of the process
*
* @throws SecurityException if a security manager exists and vetoes any
* aspect of running the process.
* @throws IOException if an I/O error occurs.
* aspect of running the process.
* @throws IOException if an I/O error occurs.
*/
public static int execute(ProcessBuilder processBuilder) throws SecurityException, IOException {
return ExecUtil.execute(processBuilder, 30, TimeUnit.DAYS, new ProcessTerminator() {
@ -110,12 +112,14 @@ public final class ExecUtil {
* Runs a process using the default timeout and a custom terminator.
*
* @param processBuilder A process builder used to configure and construct
* the process to be run.
* @param terminator The terminator.
* the process to be run.
* @param terminator The terminator.
*
* @return the exit value of the process
*
* @throws SecurityException if a security manager exists and vetoes any
* aspect of running the process.
* @throws IOException if an I/O error occurs.
* aspect of running the process.
* @throws IOException if an I/O error occurs.
*/
public static int execute(ProcessBuilder processBuilder, ProcessTerminator terminator) throws SecurityException, IOException {
return ExecUtil.execute(processBuilder, ExecUtil.DEFAULT_TIMEOUT, ExecUtil.DEFAULT_TIMEOUT_UNITS, terminator);
@ -125,14 +129,16 @@ public final class ExecUtil {
* Runs a process using a custom terminator.
*
* @param processBuilder A process builder used to configure and construct
* the process to be run.
* @param timeOut The duration of the timeout.
* @param units The units for the timeout.
* @param terminator The terminator.
* the process to be run.
* @param timeOut The duration of the timeout.
* @param units The units for the timeout.
* @param terminator The terminator.
*
* @return the exit value of the process
*
* @throws SecurityException if a security manager exists and vetoes any
* aspect of running the process.
* @throws IOException if an I/o error occurs.
* aspect of running the process.
* @throws IOException if an I/o error occurs.
*/
public static int execute(ProcessBuilder processBuilder, long timeOut, TimeUnit units, ProcessTerminator terminator) throws SecurityException, IOException {
Process process = processBuilder.start();
@ -196,7 +202,8 @@ public final class ExecUtil {
* variant with Writer.
*
* @param aCommand command to be executed
* @param params parameters of the command
* @param params parameters of the command
*
* @return string buffer with captured stdout
*/
@Deprecated
@ -241,8 +248,9 @@ public final class ExecUtil {
* and stderr to nowhere.
*
* @param stdoutWriter file writer to write stdout to
* @param aCommand command to be executed
* @param params parameters of the command
* @param aCommand command to be executed
* @param params parameters of the command
*
* @return string buffer with captured stdout
*/
@Deprecated
@ -316,7 +324,7 @@ public final class ExecUtil {
* Gets the exit value returned by the subprocess used to execute a command.
*
* @return The exit value or the distinguished value -100 if this method is
* called before the exit value is set.
* called before the exit value is set.
*/
@Deprecated
synchronized public int getExitValue() {

View File

@ -26,23 +26,26 @@ import org.openide.filesystems.FileObject;
/**
* File and dir utilities
*/
public class FileUtil {
public class FileUtil {
private static final Logger logger = Logger.getLogger(FileUtil.class.getName());
/**
* Recursively delete all of the files and sub-directories in a directory.
* Use deleteFileDir() if you are not sure if the path is a file or directory.
* Use deleteFileDir() if you are not sure if the path is a file or
* directory.
*
* @param dirPath Path of the directory to delete
* @return true if the dir was deleted with no errors. False otherwise (including if the passed in path was for a file).
*
* @return true if the dir was deleted with no errors. False otherwise
* (including if the passed in path was for a file).
*/
public static boolean deleteDir(File dirPath) {
if (dirPath.isDirectory() == false || dirPath.exists() == false) {
logger.log(Level.WARNING, "deleteDir passed in a non-directory: {0}", dirPath.getPath()); //NON-NLS
return false;
}
File[] files = dirPath.listFiles();
boolean hadErrors = false;
if (files != null) {
@ -64,16 +67,18 @@ import org.openide.filesystems.FileObject;
logger.log(Level.WARNING, "Failed to delete the empty directory at {0}", dirPath.getPath()); //NON-NLS
hadErrors = true;
}
return hadErrors;
}
/**
* Delete the file or dir at the given path. If the path is for a directory,
* Delete the file or dir at the given path. If the path is for a directory,
* recursively delete its contents.
*
* @param path the path to the file or directory to delete
* @return true if the file or directory were deleted with no errors. False otherwise.
*
* @return true if the file or directory were deleted with no errors. False
* otherwise.
*/
public static boolean deleteFileDir(File path) {
boolean sucess = true;
@ -89,21 +94,24 @@ import org.openide.filesystems.FileObject;
}
/**
* Copy a file to a new directory, potentially new file name, and overwrite old one if requested
*
* @param source source file path
* Copy a file to a new directory, potentially new file name, and overwrite
* old one if requested
*
* @param source source file path
* @param destFolder destination folder path
* @param newName file name of the copied file, which can be different from original
* @param ext file extension, e.g. ".java"
* @param overwrite if new file, already exists, overwrite it (delete it first)
* @param newName file name of the copied file, which can be different
* from original
* @param ext file extension, e.g. ".java"
* @param overwrite if new file, already exists, overwrite it (delete it
* first)
*
* @return path to the created file, or null if file was not created
*
* @throws IOException exception thrown if file copying failed
*/
public static String copyFile(String source, String destFolder, String newName, String ext, boolean overwrite)
throws IOException {
final String destFileName = destFolder + File.separator + newName + ext;
final File destFile = new File(destFileName);
if (destFile.exists()) {
@ -114,7 +122,6 @@ import org.openide.filesystems.FileObject;
}
}
final FileObject sourceFileObj = org.openide.filesystems.FileUtil.createData(new File(source));
final FileObject destFolderObj = org.openide.filesystems.FileUtil.createData(new File(destFolder));
@ -124,37 +131,40 @@ import org.openide.filesystems.FileObject;
return created.getPath();
}
/**
* Copy a folder into a new directory.
*
* @param source path to the source folder
* @param path destination path of the new folder
*
* @param source path to the source folder
* @param path destination path of the new folder
* @param folderName name of the new folder
*
*
* @return path to the new folder if created, null if it was not created
*
* @throws IOException exception thrown if file copying failed
*/
public static String copyFolder(String source, String path, String folderName) throws IOException {
String destFolder = path + File.separator + folderName;
org.openide.filesystems.FileUtil.createFolder(new File(destFolder));
final FileObject sourceFileObj = org.openide.filesystems.FileUtil.createData(new File(source));
final FileObject destFolderObj = org.openide.filesystems.FileUtil.createData(new File(destFolder));
FileObject created = org.openide.filesystems.FileUtil.copyFile(sourceFileObj, destFolderObj, sourceFileObj.getName(), sourceFileObj.getExt());
return created.getPath();
}
/**
* Escape special characters in a file name or a file name component
*
* @param fileName to escape
*
* @return escaped string
*/
public static String escapeFileName(String fileName) {
public static String escapeFileName(String fileName) {
//for now escaping / (not valid in file name, at least on Windows)
//with underscores. Windows/Java seem to ignore \\/ and \\\\/ escapings
return fileName.replaceAll("/", "_");
return fileName.replaceAll("/", "_");
}
}

View File

@ -64,7 +64,9 @@ public class ImageUtils {
private static final Logger LOGGER = Logger.getLogger(ImageUtils.class.getName());
/** save thumbnails to disk as this format */
/**
* save thumbnails to disk as this format
*/
private static final String FORMAT = "png"; //NON-NLS
public static final int ICON_SIZE_SMALL = 50;
@ -113,8 +115,10 @@ public class ImageUtils {
SUPPORTED_IMAGE_EXTENSIONS = Arrays.asList(ImageIO.getReaderFileSuffixes());
SUPPORTED_IMAGE_MIME_TYPES = new TreeSet<>(Arrays.asList(ImageIO.getReaderMIMETypes()));
/* special cases and variants that we support, but don't get registered
* with ImageIO automatically */
/*
* special cases and variants that we support, but don't get registered
* with ImageIO automatically
*/
SUPPORTED_IMAGE_MIME_TYPES.addAll(Arrays.asList(
"image/x-rgb",
"image/x-ms-bmp",
@ -124,10 +128,14 @@ public class ImageUtils {
SUPPORTED_IMAGE_MIME_TYPES.removeIf("application/octet-stream"::equals);
}
/** initialized lazily */
/**
* initialized lazily
*/
private static FileTypeDetector fileTypeDetector;
/** thread that saves generated thumbnails to disk in the background */
/**
* thread that saves generated thumbnails to disk in the background
*/
private static final Executor imageSaver
= Executors.newSingleThreadExecutor(new BasicThreadFactory.Builder()
.namingPattern("icon saver-%d").build());
@ -145,8 +153,7 @@ public class ImageUtils {
/**
* Get the default thumbnail, which is the icon for a file. Used when we can
* not
* generate content based thumbnail.
* not generate content based thumbnail.
*
* @return
*
@ -256,8 +263,8 @@ public class ImageUtils {
}
/**
* Get a thumbnail of a specified size. Generates the image if it is
* not already cached.
* Get a thumbnail of a specified size. Generates the image if it is not
* already cached.
*
* @param content
* @param iconSize
@ -277,8 +284,8 @@ public class ImageUtils {
}
/**
* Get a thumbnail of a specified size. Generates the image if it is
* not already cached.
* Get a thumbnail of a specified size. Generates the image if it is not
* already cached.
*
* @param content
* @param iconSize
@ -312,8 +319,8 @@ public class ImageUtils {
}
/**
* Get a thumbnail of a specified size. Generates the image if it is
* not already cached.
* Get a thumbnail of a specified size. Generates the image if it is not
* already cached.
*
* @param content
* @param iconSize
@ -334,8 +341,8 @@ public class ImageUtils {
/**
*
* Get a thumbnail of a specified size. Generates the image if it is
* not already cached.
* Get a thumbnail of a specified size. Generates the image if it is not
* already cached.
*
* @param content
* @param iconSize
@ -397,8 +404,10 @@ public class ImageUtils {
try {
byte[] fileHeaderBuffer = readHeader(file, 2);
/* Check for the JPEG header. Since Java bytes are signed, we cast
* them to an int first. */
/*
* Check for the JPEG header. Since Java bytes are signed, we cast
* them to an int first.
*/
return (((fileHeaderBuffer[0] & 0xff) == 0xff) && ((fileHeaderBuffer[1] & 0xff) == 0xd8));
} catch (TskCoreException ex) {
//ignore if can't read the first few bytes, not a JPEG
@ -420,8 +429,10 @@ public class ImageUtils {
try {
byte[] fileHeaderBuffer = readHeader(file, 8);
/* Check for the png header. Since Java bytes are signed, we cast
* them to an int first. */
/*
* Check for the png header. Since Java bytes are signed, we cast
* them to an int first.
*/
return (((fileHeaderBuffer[1] & 0xff) == 0x50) && ((fileHeaderBuffer[2] & 0xff) == 0x4E)
&& ((fileHeaderBuffer[3] & 0xff) == 0x47) && ((fileHeaderBuffer[4] & 0xff) == 0x0D)
&& ((fileHeaderBuffer[5] & 0xff) == 0x0A) && ((fileHeaderBuffer[6] & 0xff) == 0x1A)

View File

@ -31,14 +31,14 @@ public class Installer extends ModuleInstall {
private static Handler logs;
private static Installer instance;
public synchronized static Installer getDefault() {
if (instance == null) {
instance = new Installer();
}
return instance;
}
private Installer() {
super();
}
@ -54,14 +54,12 @@ public class Installer extends ModuleInstall {
autopsyLogger.log(Level.INFO, "Application name: " + Version.getName() //NON-NLS
+ ", version: " + Version.getVersion() + ", build: " + Version.getBuildType()); //NON-NLS NON-NLS
autopsyLogger.log(Level.INFO, "os.name: " + System.getProperty("os.name")); //NON-NLS
autopsyLogger.log(Level.INFO, "os.arch: " + System.getProperty("os.arch")); //NON-NLS
autopsyLogger.log(Level.INFO, "PID: " + PlatformUtil.getPID()); //NON-NLS
autopsyLogger.log(Level.INFO, "Process Virtual Memory Used: " + PlatformUtil.getProcessVirtualMemoryUsed()); //NON-NLS
}
@Override

View File

@ -33,7 +33,8 @@ import org.sleuthkit.autopsy.coreutils.LnkEnums.NetworkProviderType;
*
* @author dick
*/
public class JLNK {
public class JLNK {
private int header;
private byte[] linkClassIdentifier;
private List<LinkFlags> linkFlags;
@ -45,25 +46,25 @@ import org.sleuthkit.autopsy.coreutils.LnkEnums.NetworkProviderType;
private int iconIndex;
private int showCommand;
private short hotKey;
private List<String> linkTargetIdList;
private boolean hasUnicodeLocalBaseAndCommonSuffixOffset;
private String localBasePath;
private String commonPathSuffix;
private String localBasePathUnicode;
private String commonPathSuffixUnicode;
private String name;
private String relativePath;
private String workingDir;
private String arguments;
private String iconLocation;
private int driveSerialNumber;
private DriveType driveType;
private String volumeLabel;
private List<CommonNetworkRelativeLinkFlags> commonNetworkRelativeListFlags;
private NetworkProviderType networkProviderType;
private boolean unicodeNetAndDeviceName;
@ -88,14 +89,14 @@ import org.sleuthkit.autopsy.coreutils.LnkEnums.NetworkProviderType;
this.header = header;
this.linkClassIdentifier = linkClassIdentifier;
this.linkFlags = new ArrayList<LinkFlags>();
for(LnkEnums.LinkFlags enumVal : LnkEnums.LinkFlags.values()) {
if((linkFlags & enumVal.getFlag()) == enumVal.getFlag()) {
for (LnkEnums.LinkFlags enumVal : LnkEnums.LinkFlags.values()) {
if ((linkFlags & enumVal.getFlag()) == enumVal.getFlag()) {
this.linkFlags.add(enumVal);
}
}
this.fileAttributesFlags = new ArrayList<FileAttributesFlags>();
for(LnkEnums.FileAttributesFlags enumVal : LnkEnums.FileAttributesFlags.values()) {
if((fileAttributesFlags & enumVal.getFlag()) == enumVal.getFlag()) {
for (LnkEnums.FileAttributesFlags enumVal : LnkEnums.FileAttributesFlags.values()) {
if ((fileAttributesFlags & enumVal.getFlag()) == enumVal.getFlag()) {
this.fileAttributesFlags.add(enumVal);
}
}
@ -121,8 +122,8 @@ import org.sleuthkit.autopsy.coreutils.LnkEnums.NetworkProviderType;
this.driveType = driveType;
this.volumeLabel = volumeLabel;
this.commonNetworkRelativeListFlags = new ArrayList<CommonNetworkRelativeLinkFlags>();
for(LnkEnums.CommonNetworkRelativeLinkFlags enumVal : LnkEnums.CommonNetworkRelativeLinkFlags.values()) {
if((commonNetworkRelativeListFlags & enumVal.getFlag()) == enumVal.getFlag()) {
for (LnkEnums.CommonNetworkRelativeLinkFlags enumVal : LnkEnums.CommonNetworkRelativeLinkFlags.values()) {
if ((commonNetworkRelativeListFlags & enumVal.getFlag()) == enumVal.getFlag()) {
this.commonNetworkRelativeListFlags.add(enumVal);
}
}
@ -193,7 +194,7 @@ import org.sleuthkit.autopsy.coreutils.LnkEnums.NetworkProviderType;
public short getHotKey() {
return hotKey;
}
public List<String> getLinkTargetIdList() {
return linkTargetIdList;
}
@ -261,46 +262,44 @@ import org.sleuthkit.autopsy.coreutils.LnkEnums.NetworkProviderType;
public String getWorkingDir() {
return workingDir;
}
public String getBestPath() {
if(localBasePathUnicode != null && !localBasePathUnicode.isEmpty()) {
if(commonPathSuffixUnicode != null) {
if (localBasePathUnicode != null && !localBasePathUnicode.isEmpty()) {
if (commonPathSuffixUnicode != null) {
return localBasePathUnicode + commonPathSuffixUnicode;
} else if(commonPathSuffix != null) {
} else if (commonPathSuffix != null) {
return localBasePathUnicode + commonPathSuffix;
}
} else if(localBasePath != null && !localBasePath.isEmpty()) {
if(commonPathSuffixUnicode != null) {
} else if (localBasePath != null && !localBasePath.isEmpty()) {
if (commonPathSuffixUnicode != null) {
return localBasePath + commonPathSuffixUnicode;
} else if(commonPathSuffix != null) {
} else if (commonPathSuffix != null) {
return localBasePath + commonPathSuffix;
}
} else if(netNameUnicode != null && !netNameUnicode.isEmpty()) {
if(commonPathSuffixUnicode != null && !commonPathSuffixUnicode.isEmpty()) {
} else if (netNameUnicode != null && !netNameUnicode.isEmpty()) {
if (commonPathSuffixUnicode != null && !commonPathSuffixUnicode.isEmpty()) {
return netNameUnicode + "\\" + commonPathSuffixUnicode;
} else if(commonPathSuffix != null && !commonPathSuffix.isEmpty()) {
} else if (commonPathSuffix != null && !commonPathSuffix.isEmpty()) {
return netNameUnicode + "\\" + commonPathSuffix;
}
} else if(netName != null && !netName.isEmpty()) {
if(commonPathSuffixUnicode != null && !commonPathSuffixUnicode.isEmpty()) {
} else if (netName != null && !netName.isEmpty()) {
if (commonPathSuffixUnicode != null && !commonPathSuffixUnicode.isEmpty()) {
return netName + "\\" + commonPathSuffixUnicode;
} else if(commonPathSuffix != null && !commonPathSuffix.isEmpty()) {
} else if (commonPathSuffix != null && !commonPathSuffix.isEmpty()) {
return netName + "\\" + commonPathSuffix;
}
} else if(linkTargetIdList != null && !linkTargetIdList.isEmpty()) {
} else if (linkTargetIdList != null && !linkTargetIdList.isEmpty()) {
String ret = "";
for(String s : linkTargetIdList) {
for (String s : linkTargetIdList) {
ret += s;
}
return ret;
}
return NbBundle.getMessage(this.getClass(), "JLNK.noPrefPath.text");
}
public String getBestName() {
return new File(getBestPath()).getName(); // not very cross platform :(
}
}

View File

@ -32,17 +32,16 @@ import org.sleuthkit.autopsy.coreutils.LnkEnums.NetworkProviderType;
/**
*
* @author dfickling
* Parse lnk files using documentation from
* @author dfickling Parse lnk files using documentation from
* http://msdn.microsoft.com/en-us/library/dd871305(v=prot.13).aspx
* http://msdn.microsoft.com/en-us/library/windows/desktop/cc144090(v=vs.85).aspx#unknown_74413
* http://blog.0x01000000.org/2010/08/10/lnk-parsing-youre-doing-it-wrong-i/
*/
public class JLnkParser {
public class JLnkParser {
private byte[] content;
private static final Logger logger = Logger.getLogger(JLnkParser.class.getName());
public JLnkParser(InputStream is, int length) {
content = new byte[length];
try {
@ -51,7 +50,7 @@ import org.sleuthkit.autopsy.coreutils.LnkEnums.NetworkProviderType;
Logger.getLogger(JLnkParser.class.getName()).log(Level.WARNING, "Error reading input stream", ex); //NON-NLS
}
}
public JLNK parse() throws JLnkParserException {
try {
ByteBuffer bb = ByteBuffer.wrap(content);
@ -69,18 +68,18 @@ import org.sleuthkit.autopsy.coreutils.LnkEnums.NetworkProviderType;
short hotkey = bb.getShort();
bb.get(new byte[10]); // reserved (???)
List<String> linkTargetIdList = new ArrayList<String>();
if((linkFlags & LnkEnums.LinkFlags.HasLinkTargetIDList.getFlag()) ==
LnkEnums.LinkFlags.HasLinkTargetIDList.getFlag()) {
if ((linkFlags & LnkEnums.LinkFlags.HasLinkTargetIDList.getFlag())
== LnkEnums.LinkFlags.HasLinkTargetIDList.getFlag()) {
int idListSize = bb.getShort();
int bytesRead = 0;
List<byte[]> linkTargetIdListBytes = new ArrayList<byte[]>();
while(true) {
while (true) {
short itemIdSize = bb.getShort();
if(itemIdSize == 0) {
if (itemIdSize == 0) {
bytesRead += 2; // two null bytes to terminate id list
break;
}
byte[] theArray = new byte[itemIdSize-2];
byte[] theArray = new byte[itemIdSize - 2];
bb.get(theArray); // an idlist data object
linkTargetIdListBytes.add(theArray);
bytesRead = bytesRead + itemIdSize;
@ -103,8 +102,8 @@ import org.sleuthkit.autopsy.coreutils.LnkEnums.NetworkProviderType;
String deviceName = null;
String deviceNameUnicode = null;
if((linkFlags & LnkEnums.LinkFlags.HasLinkInfo.getFlag()) ==
LnkEnums.LinkFlags.HasLinkInfo.getFlag()) {
if ((linkFlags & LnkEnums.LinkFlags.HasLinkInfo.getFlag())
== LnkEnums.LinkFlags.HasLinkInfo.getFlag()) {
int startOfLinkInfo = bb.position();
int linkInfoSize = bb.getInt();
int linkInfoHeaderSize = bb.getInt();
@ -122,7 +121,7 @@ import org.sleuthkit.autopsy.coreutils.LnkEnums.NetworkProviderType;
}
if ((linkInfoFlags & LnkEnums.LinkInfoFlags.VolumeIDAndLocalBasePath.getFlag())
== LnkEnums.LinkInfoFlags.VolumeIDAndLocalBasePath.getFlag()) {
bb.position(startOfLinkInfo+volumeIdOffset);
bb.position(startOfLinkInfo + volumeIdOffset);
int volumeIdSize = bb.getInt();
driveType = DriveType.valueOf(bb.getInt());
driveSerialNumber = bb.getInt();
@ -137,7 +136,7 @@ import org.sleuthkit.autopsy.coreutils.LnkEnums.NetworkProviderType;
}
if ((linkInfoFlags & LnkEnums.LinkInfoFlags.CommonNetworkRelativeLinkAndPathSuffix.getFlag())
== LnkEnums.LinkInfoFlags.CommonNetworkRelativeLinkAndPathSuffix.getFlag()) {
bb.position(startOfLinkInfo+commonNetworkRelativeLinkOffset);
bb.position(startOfLinkInfo + commonNetworkRelativeLinkOffset);
int commonNetworkRelativeLinkSize = bb.getInt();
commonNetworkRelativeLinkFlags = bb.getInt();
int netNameOffset = bb.getInt();
@ -174,31 +173,31 @@ import org.sleuthkit.autopsy.coreutils.LnkEnums.NetworkProviderType;
commonPathSuffixUnicode = parseCommonPathSuffix(startOfLinkInfo + commonPathSuffixOffsetUnicode, true);
}
bb.position(startOfLinkInfo+linkInfoSize);
bb.position(startOfLinkInfo + linkInfoSize);
}
String name = null;
if((linkFlags & LnkEnums.LinkFlags.HasName.getFlag()) ==
LnkEnums.LinkFlags.HasName.getFlag()) {
if ((linkFlags & LnkEnums.LinkFlags.HasName.getFlag())
== LnkEnums.LinkFlags.HasName.getFlag()) {
name = readStringData(bb);
}
String relativePath = null;
if((linkFlags & LnkEnums.LinkFlags.HasRelativePath.getFlag()) ==
LnkEnums.LinkFlags.HasRelativePath.getFlag()) {
if ((linkFlags & LnkEnums.LinkFlags.HasRelativePath.getFlag())
== LnkEnums.LinkFlags.HasRelativePath.getFlag()) {
relativePath = readStringData(bb);
}
String workingDir = null;
if((linkFlags & LnkEnums.LinkFlags.HasWorkingDir.getFlag()) ==
LnkEnums.LinkFlags.HasWorkingDir.getFlag()) {
if ((linkFlags & LnkEnums.LinkFlags.HasWorkingDir.getFlag())
== LnkEnums.LinkFlags.HasWorkingDir.getFlag()) {
workingDir = readStringData(bb);
}
String arguments = null;
if((linkFlags & LnkEnums.LinkFlags.HasArguments.getFlag()) ==
LnkEnums.LinkFlags.HasArguments.getFlag()) {
if ((linkFlags & LnkEnums.LinkFlags.HasArguments.getFlag())
== LnkEnums.LinkFlags.HasArguments.getFlag()) {
arguments = readStringData(bb);
}
String iconLocation = null;
if((linkFlags & LnkEnums.LinkFlags.HasIconLocation.getFlag()) ==
LnkEnums.LinkFlags.HasIconLocation.getFlag()) {
if ((linkFlags & LnkEnums.LinkFlags.HasIconLocation.getFlag())
== LnkEnums.LinkFlags.HasIconLocation.getFlag()) {
iconLocation = readStringData(bb);
}
@ -215,13 +214,13 @@ import org.sleuthkit.autopsy.coreutils.LnkEnums.NetworkProviderType;
throw new JLnkParserException(e);
}
}
private String readStringData(ByteBuffer bb) {
short countCharacters = bb.getShort();
if(countCharacters == 0) {
if (countCharacters == 0) {
return null;
}
byte[] theString = new byte[countCharacters*2];
byte[] theString = new byte[countCharacters * 2];
bb.get(theString);
try {
return new String(theString, "UTF-16LE");
@ -230,7 +229,7 @@ import org.sleuthkit.autopsy.coreutils.LnkEnums.NetworkProviderType;
return null;
}
}
private String parseString(int offset, boolean unicode, int maxlen) {
ByteBuffer bb = ByteBuffer.wrap(content);
bb.order(ByteOrder.LITTLE_ENDIAN);
@ -240,7 +239,7 @@ import org.sleuthkit.autopsy.coreutils.LnkEnums.NetworkProviderType;
while (bb.remaining() > 0 && (i < maxlen || maxlen == -1)) // safer
{
char c;
if(unicode) {
if (unicode) {
c = bb.getChar();
} else {
c = (char) bb.get();
@ -253,28 +252,28 @@ import org.sleuthkit.autopsy.coreutils.LnkEnums.NetworkProviderType;
}
return sb.toString();
}
private String parseCommonPathSuffix(int offset, boolean unicode) {
return parseString(offset, unicode, -1);
}
private String parseLocalBasePath(int offset, boolean unicode) {
return parseString(offset, unicode, -1);
}
private String parseNetName(int offset, boolean unicode) {
return parseString(offset, unicode, -1);
}
private String parseDeviceName(int offset, boolean unicode) {
return parseString(offset, unicode, -1);
}
private List<String> parseLinkTargetIdList(List<byte[]> idList) {
List<String> ret = new ArrayList<String>();
if(!idList.isEmpty()) {
if (!idList.isEmpty()) {
CommonCLSIDS clsid = CommonCLSIDS.valueOf(Arrays.copyOfRange(idList.remove(0), 2, 18));
switch (clsid) {
case CDrivesFolder:
@ -294,13 +293,13 @@ import org.sleuthkit.autopsy.coreutils.LnkEnums.NetworkProviderType;
}
return ret;
}
private List<String> parsePathElements(List<byte[]> idList) {
List<String> ret = new ArrayList<String>();
for (byte[] pathElement : idList) {
ByteBuffer bb = ByteBuffer.wrap(pathElement);
bb.order(ByteOrder.LITTLE_ENDIAN);
int offset = bb.getShort(bb.limit() - 2)-2;
int offset = bb.getShort(bb.limit() - 2) - 2;
if (pathElement[offset + 0x02] < 0x03
|| pathElement[offset + 0x10] >= pathElement[offset]
|| pathElement[offset + 0x10] < 0x14) {
@ -323,7 +322,7 @@ import org.sleuthkit.autopsy.coreutils.LnkEnums.NetworkProviderType;
}
return ret;
}
private String get0xC(ByteBuffer bb) {
return getStringAt(bb, 0xC, false);
}
@ -340,5 +339,3 @@ import org.sleuthkit.autopsy.coreutils.LnkEnums.NetworkProviderType;
return new String(nameArr).split("\0")[0];
}
}

View File

@ -22,11 +22,11 @@ package org.sleuthkit.autopsy.coreutils;
*
* @author jwallace
*/
public class JLnkParserException extends Exception {
public class JLnkParserException extends Exception {
/**
* Constructs an instance of
* <code>JLnkParserException</code> caused by the given exception.
* Constructs an instance of <code>JLnkParserException</code> caused by the
* given exception.
*
* @param msg the detail message.
*/

Some files were not shown because too many files have changed in this diff Show More