From 219bb5b2e06da3d2a09bb1c4409ea381ce61be6a Mon Sep 17 00:00:00 2001 From: esaunders Date: Wed, 11 Mar 2020 11:21:47 -0400 Subject: [PATCH 01/41] Upgrade version of JNA. --- Core/nbproject/project.properties | 2 -- Core/nbproject/project.xml | 4 ---- CoreLibs/ivy.xml | 6 +----- CoreLibs/nbproject/project.properties | 4 ++-- CoreLibs/nbproject/project.xml | 16 ++++++++-------- 5 files changed, 11 insertions(+), 21 deletions(-) diff --git a/Core/nbproject/project.properties b/Core/nbproject/project.properties index 94dffdeb9b..80e8cfd4d4 100644 --- a/Core/nbproject/project.properties +++ b/Core/nbproject/project.properties @@ -45,7 +45,6 @@ file.reference.jericho-html-3.3.jar=release/modules/ext/jericho-html-3.3.jar file.reference.jgraphx-v3.8.0.jar=release/modules/ext/jgraphx-v3.8.0.jar file.reference.jhighlight-1.0.3.jar=release\\modules\\ext\\jhighlight-1.0.3.jar file.reference.jmatio-1.5.jar=release\\modules\\ext\\jmatio-1.5.jar -file.reference.jna-5.1.0.jar=release\\modules\\ext\\jna-5.1.0.jar file.reference.json-simple-1.1.1.jar=release\\modules\\ext\\json-simple-1.1.1.jar file.reference.jsoup-1.11.3.jar=release\\modules\\ext\\jsoup-1.11.3.jar file.reference.jul-to-slf4j-1.7.25.jar=release\\modules\\ext\\jul-to-slf4j-1.7.25.jar @@ -97,7 +96,6 @@ file.reference.xz-1.8.jar=release\\modules\\ext\\xz-1.8.jar file.reference.zookeeper-3.4.6.jar=release/modules/ext/zookeeper-3.4.6.jar file.reference.SparseBitSet-1.1.jar=release/modules/ext/SparseBitSet-1.1.jar file.reference.commons-validator-1.6.jar=release/modules/ext/commons-validator-1.6.jar -file.reference.jna-3.4.0.jar=release/modules/ext/jna-3.4.0.jar file.reference.api-common-1.7.0.jar=release/modules/ext/api-common-1.7.0.jar file.reference.gax-1.44.0.jar=release/modules/ext/gax-1.44.0.jar file.reference.gax-grpc-1.44.0.jar=release/modules/ext/gax-grpc-1.44.0.jar diff --git a/Core/nbproject/project.xml b/Core/nbproject/project.xml index 182b92a661..02d37221a7 100644 --- a/Core/nbproject/project.xml +++ b/Core/nbproject/project.xml @@ -615,10 +615,6 @@ ext/commons-validator-1.6.jar release/modules/ext/commons-validator-1.6.jar - - ext/jna-5.1.0.jar - release\modules\ext\jna-5.1.0.jar - ext/jbig2-imageio-3.0.2.jar release\modules\ext\jbig2-imageio-3.0.2.jar diff --git a/CoreLibs/ivy.xml b/CoreLibs/ivy.xml index 6819dac82d..4853d1f90e 100644 --- a/CoreLibs/ivy.xml +++ b/CoreLibs/ivy.xml @@ -14,8 +14,7 @@ - - + @@ -73,8 +72,5 @@ - - - diff --git a/CoreLibs/nbproject/project.properties b/CoreLibs/nbproject/project.properties index 677f823e67..42f8292d5b 100644 --- a/CoreLibs/nbproject/project.properties +++ b/CoreLibs/nbproject/project.properties @@ -21,7 +21,6 @@ file.reference.dom4j-1.6.1.jar=release/modules/ext/dom4j-1.6.1.jar file.reference.geronimo-jms_1.1_spec-1.0.jar=release/modules/ext/geronimo-jms_1.1_spec-1.0.jar file.reference.gson-2.8.5.jar=release/modules/ext/gson-2.8.5.jar file.reference.gst1-java-core-1.0.0.jar=release\\modules\\ext\\gst1-java-core-1.0.0.jar -file.reference.jna-3.4.0.jar=release/modules/ext/jna-3.4.0.jar file.reference.guava-19.0.jar=release/modules/ext/guava-19.0.jar file.reference.imageio-bmp-3.2.jar=release/modules/ext/imageio-bmp-3.2.jar file.reference.imageio-core-3.2.jar=release/modules/ext/imageio-core-3.2.jar @@ -44,6 +43,8 @@ file.reference.jfxtras-common-8.0-r4.jar=release/modules/ext/jfxtras-common-8.0- file.reference.jfxtras-controls-8.0-r4.jar=release/modules/ext/jfxtras-controls-8.0-r4.jar file.reference.jfxtras-fxml-8.0-r4.jar=release/modules/ext/jfxtras-fxml-8.0-r4.jar file.reference.jna-3.4.0.jar=release/modules/ext/jna-3.4.0.jar +file.reference.jna-5.5.0.jar=release\\modules\\ext\\jna-5.5.0.jar +file.reference.jna-platform-5.5.0.jar=release\\modules\\ext\\jna-platform-5.5.0.jar file.reference.joda-time-2.4.jar=release/modules/ext/joda-time-2.4.jar file.reference.jsr305-1.3.9.jar=release/modules/ext/jsr305-1.3.9.jar file.reference.LGoodDatePicker-10.3.1.jar=release/modules/ext/LGoodDatePicker-10.3.1.jar @@ -52,7 +53,6 @@ file.reference.logkit-1.0.1.jar=release/modules/ext/logkit-1.0.1.jar file.reference.mail-1.4.3.jar=release/modules/ext/mail-1.4.3.jar file.reference.opencv-248.jar=release/modules/ext/opencv-248.jar file.reference.openjfx-dialogs-1.0.2.jar=release/modules/ext/openjfx-dialogs-1.0.3.jar -file.reference.platform-3.4.0.jar=release/modules/ext/platform-3.4.0.jar file.reference.poi-4.0.1.jar=release\\modules\\ext\\poi-4.0.1.jar file.reference.poi-excelant-4.0.1.jar=release\\modules\\ext\\poi-excelant-4.0.1.jar file.reference.poi-ooxml-4.0.1.jar=release\\modules\\ext\\poi-ooxml-4.0.1.jar diff --git a/CoreLibs/nbproject/project.xml b/CoreLibs/nbproject/project.xml index 0498669b04..d5169a8965 100644 --- a/CoreLibs/nbproject/project.xml +++ b/CoreLibs/nbproject/project.xml @@ -806,10 +806,6 @@ ext/sigar-1.6.4.jar release/modules/ext/sigar-1.6.4.jar - - ext/jna-3.4.0.jar - release/modules/ext/jna-3.4.0.jar - ext/gson-2.8.5.jar release/modules/ext/gson-2.8.5.jar @@ -902,6 +898,10 @@ ext/commons-csv-1.4.jar release/modules/ext/commons-csv-1.4.jar + + ext/jna-5.5.0.jar + release/modules/ext/jna-5.5.0.jar + ext/imageio-sgi-3.2.jar release/modules/ext/imageio-sgi-3.2.jar @@ -946,10 +946,6 @@ ext/imageio-bmp-3.2.jar release/modules/ext/imageio-bmp-3.2.jar - - ext/platform-3.4.0.jar - release/modules/ext/platform-3.4.0.jar - ext/commons-lang-2.6.jar release/modules/ext/commons-lang-2.6.jar @@ -1018,6 +1014,10 @@ ext/dom4j-1.6.1.jar release/modules/ext/dom4j-1.6.1.jar + + ext/jna-platform-5.5.0.jar + release/modules/ext/jna-platform-5.5.0.jar + ext/imageio-metadata-3.2.jar release/modules/ext/imageio-metadata-3.2.jar From c64cbb351f023c844ebd779720a790a51bddc53e Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Wed, 11 Mar 2020 12:07:29 -0400 Subject: [PATCH 02/41] 6111: CVT displays incorrect To phone number for Outgoing calls. --- .../relationships/CallLogNode.java | 60 ++++++++++++++++--- 1 file changed, 51 insertions(+), 9 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java index 288b3efa3f..055cddcc09 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java @@ -19,6 +19,7 @@ package org.sleuthkit.autopsy.communications.relationships; import java.util.logging.Level; +import org.apache.commons.lang.StringUtils; import org.openide.nodes.Sheet; import org.sleuthkit.autopsy.communications.Utils; import static org.sleuthkit.autopsy.communications.relationships.RelationshipsNodeUtilities.getAttributeDisplayString; @@ -67,14 +68,6 @@ final class CallLogNode extends BlackboardArtifactNode { return sheet; } - String phoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_FROM); - if(phoneNumber == null || phoneNumber.isEmpty()) { - phoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_TO); - } - if(phoneNumber == null || phoneNumber.isEmpty()) { - phoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER); - } - long duration = -1; try{ duration = getCallDuration(artifact); @@ -84,7 +77,7 @@ final class CallLogNode extends BlackboardArtifactNode { sheetSet.put(createNode(TSK_DATETIME_START, artifact)); sheetSet.put(createNode(TSK_DIRECTION, artifact)); - sheetSet.put(new NodeProperty<>(TSK_PHONE_NUMBER.getLabel(), TSK_PHONE_NUMBER.getDisplayName(), "", phoneNumber)); + sheetSet.put(new NodeProperty<>(TSK_PHONE_NUMBER.getLabel(), TSK_PHONE_NUMBER.getDisplayName(), "", getPhoneNumber(artifact))); if(duration != -1) { sheetSet.put(new NodeProperty<>("duration", "Duration", "", Long.toString(duration))); } @@ -107,6 +100,55 @@ final class CallLogNode extends BlackboardArtifactNode { return endAttribute.getValueLong() - startAttribute.getValueLong(); } + /** + * Returns the phone number to display in the To/From column. The number is + * picked from one the the 3 possible phone number attributes, based on the + * direction of the call. + * + * @param artifact Call log artifact. + * + * @return Phone number. + */ + private String getPhoneNumber(BlackboardArtifact artifact) { + String direction = getAttributeDisplayString(artifact, TSK_DIRECTION); + + String phoneNumberToReturn = ""; + String fromPhoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_FROM); + String toPhoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_TO); + String phoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER); + + switch (direction.toLowerCase()) { + case "incoming": // NON-NLS + + if (!StringUtils.isBlank(fromPhoneNumber)) { + phoneNumberToReturn = fromPhoneNumber; + } else if (!StringUtils.isBlank(phoneNumber)) { + phoneNumberToReturn = phoneNumber; + } else if (!StringUtils.isBlank(toPhoneNumber)) { + phoneNumberToReturn = toPhoneNumber; + } + break; + case "outgoing": // NON-NLS + if (!StringUtils.isBlank(toPhoneNumber)) { + phoneNumberToReturn = toPhoneNumber; + } else if (!StringUtils.isBlank(phoneNumber)) { + phoneNumberToReturn = phoneNumber; + } else if (!StringUtils.isBlank(fromPhoneNumber)) { + phoneNumberToReturn = fromPhoneNumber; + } + break; + default: + if (!StringUtils.isBlank(toPhoneNumber)) { + phoneNumberToReturn = toPhoneNumber; + } else if (!StringUtils.isBlank(fromPhoneNumber)) { + phoneNumberToReturn = fromPhoneNumber; + } else if (!StringUtils.isBlank(phoneNumber)) { + phoneNumberToReturn = phoneNumber; + } + } + + return phoneNumberToReturn; + } /** * Circumvent DataResultFilterNode's slightly odd delegation to * BlackboardArtifactNode.getSourceName(). From 92a3667a1419c68d73a5cd6d8bdadb67cf5cb674 Mon Sep 17 00:00:00 2001 From: esaunders Date: Wed, 11 Mar 2020 12:08:56 -0400 Subject: [PATCH 03/41] Revert Gst initialization on Windows since it didn't have any impact on crashes. --- .../contentviewers/MediaPlayerPanel.java | 86 +++++++++---------- 1 file changed, 41 insertions(+), 45 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java index c518abdd45..6df0cf8161 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java @@ -74,7 +74,6 @@ import org.freedesktop.gstreamer.Format; import org.freedesktop.gstreamer.GstException; import org.freedesktop.gstreamer.event.SeekFlags; import org.freedesktop.gstreamer.event.SeekType; -import org.sleuthkit.autopsy.coreutils.PlatformUtil; /** * This is a video player that is part of the Media View layered pane. It uses @@ -222,14 +221,6 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie //True for fairness. In other words, //acquire() calls are processed in order of invocation. sliderLock = new Semaphore(1, true); - - /** - * See JIRA-5888 for details. Initializing gstreamer here is more stable - * on Windows. - */ - if (PlatformUtil.isWindowsOS()) { - Gst.init(); - } } private void customizeComponents() { @@ -264,7 +255,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie //Manage the video while the user is performing actions on the track. progressSlider.addMouseListener(new MouseListener() { private State previousState = State.NULL; - + @Override public void mousePressed(MouseEvent e) { previousState = gstPlayBin.getState(); @@ -273,11 +264,12 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie @Override public void mouseReleased(MouseEvent e) { - if(previousState.equals(State.PLAYING)) { + if (previousState.equals(State.PLAYING)) { gstPlayBin.play(); } previousState = State.NULL; } + @Override public void mouseClicked(MouseEvent e) { } @@ -289,7 +281,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie @Override public void mouseExited(MouseEvent e) { } - + }); //Manage the audio level when the user is adjusting the volume slider audioSlider.addChangeListener((ChangeEvent event) -> { @@ -389,6 +381,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie gstPlayBin.getBus().disconnect(endOfStreamListener); gstPlayBin.getBus().disconnect(stateChangeListener); gstPlayBin.getBus().disconnect(errorListener); + gstPlayBin.getBus().dispose(); gstPlayBin.dispose(); fxAppSink.clear(); gstPlayBin = null; @@ -548,10 +541,8 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie // Initialize Gstreamer. It is safe to call this for every file. // It was moved here from the constructor because having it happen - // earlier resulted in conflicts on Linux. See JIRA-5888. - if (!PlatformUtil.isWindowsOS()) { - Gst.init(); - } + // earlier resulted in crashes on Linux. See JIRA-5888. + Gst.init(); //Video is ready for playback. Create new components gstPlayBin = new PlayBin("VideoPlayer", tempFile.toURI()); @@ -599,23 +590,27 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie @Override public void actionPerformed(ActionEvent e) { if (!progressSlider.getValueIsAdjusting()) { - sliderLock.acquireUninterruptibly(); - long position = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); - long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); - /** - * Duration may not be known until there is video data in the - * pipeline. We start this updater when data-flow has just been - * initiated so buffering may still be in progress. - */ - if (duration >= 0 && position >= 0) { - double relativePosition = (double) position / duration; - progressSlider.setValue((int) (relativePosition * PROGRESS_SLIDER_SIZE)); - } + try { + sliderLock.acquireUninterruptibly(); + long position = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); + long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); + /** + * Duration may not be known until there is video data in + * the pipeline. We start this updater when data-flow has + * just been initiated so buffering may still be in + * progress. + */ + if (duration >= 0 && position >= 0) { + double relativePosition = (double) position / duration; + progressSlider.setValue((int) (relativePosition * PROGRESS_SLIDER_SIZE)); + } - SwingUtilities.invokeLater(() -> { - updateTimeLabel(position, duration); - }); - sliderLock.release(); + SwingUtilities.invokeLater(() -> { + updateTimeLabel(position, duration); + }); + } finally { + sliderLock.release(); + } } } } @@ -635,13 +630,13 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie * thumb at the given width and height. It also paints the track blue as * the thumb progresses. * - * @param slider JSlider component + * @param slider JSlider component * @param thumbDimension */ public CircularJSliderUI(JSlider slider, Dimension thumbDimension) { super(slider); this.thumbDimension = thumbDimension; - + //Configure track and thumb colors. Color lightBlue = new Color(0, 130, 255); thumbColor = lightBlue; @@ -655,8 +650,8 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie } /** - * Modifies the View to be an oval rather than the underlying - * rectangle Controller. + * Modifies the View to be an oval rather than the underlying rectangle + * Controller. */ @Override public void paintThumb(Graphics graphic) { @@ -705,12 +700,13 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie @Override protected TrackListener createTrackListener(JSlider slider) { /** - * This track listener will force the thumb to be snapped to the mouse - * location. This makes grabbing and dragging the JSlider much easier. - * Using the default track listener, the user would have to click - * exactly on the slider thumb to drag it. Now the thumb positions - * itself under the mouse so that it can always be dragged. - */ + * This track listener will force the thumb to be snapped to the + * mouse location. This makes grabbing and dragging the JSlider much + * easier. Using the default track listener, the user would have to + * click exactly on the slider thumb to drag it. Now the thumb + * positions itself under the mouse so that it can always be + * dragged. + */ return new TrackListener() { @Override public void mousePressed(MouseEvent e) { @@ -1007,14 +1003,14 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie //Don't allow skipping within 2 seconds of video ending. Skipping right to //the end causes undefined behavior for some gstreamer plugins. long twoSecondsInNano = TimeUnit.NANOSECONDS.convert(2, TimeUnit.SECONDS); - if((duration - currentTime) <= twoSecondsInNano) { + if ((duration - currentTime) <= twoSecondsInNano) { return; } - + long newTime; if (currentTime + fastForwardDelta >= duration) { //If there are less than 30 seconds left, only fast forward to the midpoint. - newTime = currentTime + (duration - currentTime)/2; + newTime = currentTime + (duration - currentTime) / 2; } else { newTime = currentTime + fastForwardDelta; } From ad5106d7d431aaf4d1eba68aff3c737b83d65c7b Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Wed, 11 Mar 2020 13:43:31 -0400 Subject: [PATCH 04/41] Addressed Codacy comments. --- .../relationships/CallLogNode.java | 56 ++++++++++--------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java index 055cddcc09..3151d75780 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/CallLogNode.java @@ -102,53 +102,57 @@ final class CallLogNode extends BlackboardArtifactNode { /** * Returns the phone number to display in the To/From column. The number is - * picked from one the the 3 possible phone number attributes, based on the + * picked from one of the 3 possible phone number attributes, based on the * direction of the call. * * @param artifact Call log artifact. * - * @return Phone number. + * @return Phone number to display. */ private String getPhoneNumber(BlackboardArtifact artifact) { String direction = getAttributeDisplayString(artifact, TSK_DIRECTION); - String phoneNumberToReturn = ""; + String phoneNumberToReturn; String fromPhoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_FROM); String toPhoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER_TO); String phoneNumber = getAttributeDisplayString(artifact, TSK_PHONE_NUMBER); - switch (direction.toLowerCase()) { case "incoming": // NON-NLS - - if (!StringUtils.isBlank(fromPhoneNumber)) { - phoneNumberToReturn = fromPhoneNumber; - } else if (!StringUtils.isBlank(phoneNumber)) { - phoneNumberToReturn = phoneNumber; - } else if (!StringUtils.isBlank(toPhoneNumber)) { - phoneNumberToReturn = toPhoneNumber; - } + phoneNumberToReturn = getFirstNonBlank(fromPhoneNumber, phoneNumber, toPhoneNumber); break; case "outgoing": // NON-NLS - if (!StringUtils.isBlank(toPhoneNumber)) { - phoneNumberToReturn = toPhoneNumber; - } else if (!StringUtils.isBlank(phoneNumber)) { - phoneNumberToReturn = phoneNumber; - } else if (!StringUtils.isBlank(fromPhoneNumber)) { - phoneNumberToReturn = fromPhoneNumber; - } + phoneNumberToReturn = getFirstNonBlank(toPhoneNumber, phoneNumber, fromPhoneNumber); break; default: - if (!StringUtils.isBlank(toPhoneNumber)) { - phoneNumberToReturn = toPhoneNumber; - } else if (!StringUtils.isBlank(fromPhoneNumber)) { - phoneNumberToReturn = fromPhoneNumber; - } else if (!StringUtils.isBlank(phoneNumber)) { - phoneNumberToReturn = phoneNumber; - } + phoneNumberToReturn = getFirstNonBlank(toPhoneNumber, fromPhoneNumber, phoneNumber ); + break; } return phoneNumberToReturn; } + + /** + * Checks the given string arguments in order and returns the first non blank string. + * Returns a blank string if all the input strings are blank. + * + * @param string1 First string to check + * @param string2 Second string to check + * @param string3 Third string to check + * + * @retunr first non blank string if there is one, blank string otherwise. + * + */ + private String getFirstNonBlank(String string1, String string2, String string3 ) { + + if (!StringUtils.isBlank(string1)) { + return string1; + } else if (!StringUtils.isBlank(string2)) { + return string2; + } else if (!StringUtils.isBlank(string3)) { + return string3; + } + return ""; + } /** * Circumvent DataResultFilterNode's slightly odd delegation to * BlackboardArtifactNode.getSourceName(). From 1581e07ea29d764536590500b72c50898dd3ee92 Mon Sep 17 00:00:00 2001 From: esaunders Date: Wed, 11 Mar 2020 16:35:22 -0400 Subject: [PATCH 05/41] Make all interactions with Gstreamer happen on the GST Java bindings service thread. --- .../contentviewers/MediaPlayerPanel.java | 265 ++++++++++-------- 1 file changed, 145 insertions(+), 120 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java index 6df0cf8161..d2d8ace001 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java @@ -377,14 +377,16 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie } timer.stop(); if (gstPlayBin != null) { - gstPlayBin.stop(); - gstPlayBin.getBus().disconnect(endOfStreamListener); - gstPlayBin.getBus().disconnect(stateChangeListener); - gstPlayBin.getBus().disconnect(errorListener); - gstPlayBin.getBus().dispose(); - gstPlayBin.dispose(); - fxAppSink.clear(); - gstPlayBin = null; + Gst.getExecutor().submit(() -> { + gstPlayBin.stop(); + gstPlayBin.getBus().disconnect(endOfStreamListener); + gstPlayBin.getBus().disconnect(stateChangeListener); + gstPlayBin.getBus().disconnect(errorListener); + gstPlayBin.getBus().dispose(); + gstPlayBin.dispose(); + fxAppSink.clear(); + gstPlayBin = null; + }); } videoPanel.removeAll(); resetComponents(); @@ -539,39 +541,52 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie return; } + // Setting the following property causes the GST + // Java bindings to call dispose() on the GST + // service thread instead of running it in the GST + // Native Object Reaper thread. + System.setProperty("glib.reapOnEDT", "true"); + // Initialize Gstreamer. It is safe to call this for every file. // It was moved here from the constructor because having it happen // earlier resulted in crashes on Linux. See JIRA-5888. Gst.init(); - //Video is ready for playback. Create new components - gstPlayBin = new PlayBin("VideoPlayer", tempFile.toURI()); - //Configure event handling - Bus playBinBus = gstPlayBin.getBus(); - playBinBus.connect(endOfStreamListener); - playBinBus.connect(stateChangeListener); - playBinBus.connect(errorListener); - - if (this.isCancelled()) { + if (!Gst.isInitialized()) { + logger.log(Level.INFO, "GStreamer is not initialized."); //NON-NLS return; } - JFXPanel fxPanel = new JFXPanel(); - videoPanel.removeAll(); - videoPanel.setLayout(new BoxLayout(videoPanel, BoxLayout.Y_AXIS)); - videoPanel.add(fxPanel); - fxAppSink = new JavaFxAppSink("JavaFxAppSink", fxPanel); - gstPlayBin.setVideoSink(fxAppSink); + Gst.getExecutor().submit(() -> { + //Video is ready for playback. Create new components + gstPlayBin = new PlayBin("VideoPlayer", tempFile.toURI()); + //Configure event handling + Bus playBinBus = gstPlayBin.getBus(); + playBinBus.connect(endOfStreamListener); + playBinBus.connect(stateChangeListener); + playBinBus.connect(errorListener); - if (this.isCancelled()) { - return; - } + if (this.isCancelled()) { + return; + } - gstPlayBin.setVolume((audioSlider.getValue() * 2.0) / 100.0); - gstPlayBin.pause(); + JFXPanel fxPanel = new JFXPanel(); + videoPanel.removeAll(); + videoPanel.setLayout(new BoxLayout(videoPanel, BoxLayout.Y_AXIS)); + videoPanel.add(fxPanel); + fxAppSink = new JavaFxAppSink("JavaFxAppSink", fxPanel); + gstPlayBin.setVideoSink(fxAppSink); - timer.start(); - enableComponents(true); + if (this.isCancelled()) { + return; + } + + gstPlayBin.setVolume((audioSlider.getValue() * 2.0) / 100.0); + gstPlayBin.pause(); + + timer.start(); + enableComponents(true); + }); } catch (CancellationException ex) { logger.log(Level.INFO, "Media buffering was canceled."); //NON-NLS } catch (InterruptedException ex) { @@ -588,29 +603,31 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie private class VideoPanelUpdater implements ActionListener { @Override - public void actionPerformed(ActionEvent e) { + public void actionPerformed(ActionEvent e) { if (!progressSlider.getValueIsAdjusting()) { - try { - sliderLock.acquireUninterruptibly(); - long position = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); - long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); - /** - * Duration may not be known until there is video data in - * the pipeline. We start this updater when data-flow has - * just been initiated so buffering may still be in - * progress. - */ - if (duration >= 0 && position >= 0) { - double relativePosition = (double) position / duration; - progressSlider.setValue((int) (relativePosition * PROGRESS_SLIDER_SIZE)); - } + Gst.getExecutor().submit(() -> { + try { + sliderLock.acquireUninterruptibly(); + long position = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); + long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); + /** + * Duration may not be known until there is video data + * in the pipeline. We start this updater when data-flow + * has just been initiated so buffering may still be in + * progress. + */ + if (duration >= 0 && position >= 0) { + double relativePosition = (double) position / duration; + progressSlider.setValue((int) (relativePosition * PROGRESS_SLIDER_SIZE)); + } - SwingUtilities.invokeLater(() -> { - updateTimeLabel(position, duration); - }); - } finally { - sliderLock.release(); - } + SwingUtilities.invokeLater(() -> { + updateTimeLabel(position, duration); + }); + } finally { + sliderLock.release(); + } + }); } } } @@ -978,87 +995,95 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie }// //GEN-END:initComponents private void rewindButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rewindButtonActionPerformed - long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); - //Skip 30 seconds. - long rewindDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); - //Ensure new video position is within bounds - long newTime = Math.max(currentTime - rewindDelta, 0); - double playBackRate = getPlayBackRate(); - gstPlayBin.seek(playBackRate, - Format.TIME, - //FLUSH - flushes the pipeline - //ACCURATE - video will seek exactly to the position requested - EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), - //Set the start position to newTime - SeekType.SET, newTime, - //Do nothing for the end position - SeekType.NONE, -1); - }//GEN-LAST:event_rewindButtonActionPerformed - - private void fastForwardButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fastForwardButtonActionPerformed - long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); - long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); - //Skip 30 seconds. - long fastForwardDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); - //Don't allow skipping within 2 seconds of video ending. Skipping right to - //the end causes undefined behavior for some gstreamer plugins. - long twoSecondsInNano = TimeUnit.NANOSECONDS.convert(2, TimeUnit.SECONDS); - if ((duration - currentTime) <= twoSecondsInNano) { - return; - } - - long newTime; - if (currentTime + fastForwardDelta >= duration) { - //If there are less than 30 seconds left, only fast forward to the midpoint. - newTime = currentTime + (duration - currentTime) / 2; - } else { - newTime = currentTime + fastForwardDelta; - } - - double playBackRate = getPlayBackRate(); - gstPlayBin.seek(playBackRate, - Format.TIME, - //FLUSH - flushes the pipeline - //ACCURATE - video will seek exactly to the position requested - EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), - //Set the start position to newTime - SeekType.SET, newTime, - //Do nothing for the end position - SeekType.NONE, -1); - }//GEN-LAST:event_fastForwardButtonActionPerformed - - private void playButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playButtonActionPerformed - if (gstPlayBin.isPlaying()) { - gstPlayBin.pause(); - } else { - double playBackRate = getPlayBackRate(); + Gst.getExecutor().submit(() -> { long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); - //Set playback rate before play. + //Skip 30 seconds. + long rewindDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); + //Ensure new video position is within bounds + long newTime = Math.max(currentTime - rewindDelta, 0); + double playBackRate = getPlayBackRate(); gstPlayBin.seek(playBackRate, Format.TIME, //FLUSH - flushes the pipeline //ACCURATE - video will seek exactly to the position requested EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), //Set the start position to newTime - SeekType.SET, currentTime, + SeekType.SET, newTime, //Do nothing for the end position SeekType.NONE, -1); - gstPlayBin.play(); - } + }); + }//GEN-LAST:event_rewindButtonActionPerformed + + private void fastForwardButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fastForwardButtonActionPerformed + Gst.getExecutor().submit(() -> { + long duration = gstPlayBin.queryDuration(TimeUnit.NANOSECONDS); + long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); + //Skip 30 seconds. + long fastForwardDelta = TimeUnit.NANOSECONDS.convert(SKIP_IN_SECONDS, TimeUnit.SECONDS); + //Don't allow skipping within 2 seconds of video ending. Skipping right to + //the end causes undefined behavior for some gstreamer plugins. + long twoSecondsInNano = TimeUnit.NANOSECONDS.convert(2, TimeUnit.SECONDS); + if ((duration - currentTime) <= twoSecondsInNano) { + return; + } + + long newTime; + if (currentTime + fastForwardDelta >= duration) { + //If there are less than 30 seconds left, only fast forward to the midpoint. + newTime = currentTime + (duration - currentTime) / 2; + } else { + newTime = currentTime + fastForwardDelta; + } + + double playBackRate = getPlayBackRate(); + gstPlayBin.seek(playBackRate, + Format.TIME, + //FLUSH - flushes the pipeline + //ACCURATE - video will seek exactly to the position requested + EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), + //Set the start position to newTime + SeekType.SET, newTime, + //Do nothing for the end position + SeekType.NONE, -1); + }); + }//GEN-LAST:event_fastForwardButtonActionPerformed + + private void playButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playButtonActionPerformed + Gst.getExecutor().submit(() -> { + if (gstPlayBin.isPlaying()) { + gstPlayBin.pause(); + } else { + double playBackRate = getPlayBackRate(); + long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); + //Set playback rate before play. + gstPlayBin.seek(playBackRate, + Format.TIME, + //FLUSH - flushes the pipeline + //ACCURATE - video will seek exactly to the position requested + EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), + //Set the start position to newTime + SeekType.SET, currentTime, + //Do nothing for the end position + SeekType.NONE, -1); + gstPlayBin.play(); + } + }); }//GEN-LAST:event_playButtonActionPerformed private void playBackSpeedComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_playBackSpeedComboBoxActionPerformed - double playBackRate = getPlayBackRate(); - long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); - gstPlayBin.seek(playBackRate, - Format.TIME, - //FLUSH - flushes the pipeline - //ACCURATE - video will seek exactly to the position requested - EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), - //Set the position to the currentTime, we are only adjusting the - //playback rate. - SeekType.SET, currentTime, - SeekType.NONE, 0); + Gst.getExecutor().submit(() -> { + double playBackRate = getPlayBackRate(); + long currentTime = gstPlayBin.queryPosition(TimeUnit.NANOSECONDS); + gstPlayBin.seek(playBackRate, + Format.TIME, + //FLUSH - flushes the pipeline + //ACCURATE - video will seek exactly to the position requested + EnumSet.of(SeekFlags.FLUSH, SeekFlags.ACCURATE), + //Set the position to the currentTime, we are only adjusting the + //playback rate. + SeekType.SET, currentTime, + SeekType.NONE, 0); + }); }//GEN-LAST:event_playBackSpeedComboBoxActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables From a158cfcf699742431a9e80243734a68b66c237e7 Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Fri, 13 Mar 2020 13:56:58 -0400 Subject: [PATCH 06/41] 6147: Do not create device accounts in Central Repo --- .../CorrelationAttributeInstance.java | 3 +- .../datamodel/CorrelationAttributeUtil.java | 39 ++++++++++-------- .../datamodel/RdbmsCentralRepoFactory.java | 41 ++++--------------- 3 files changed, 32 insertions(+), 51 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java index 1ab978bc84..4d5e2857a1 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeInstance.java @@ -294,8 +294,9 @@ public class CorrelationAttributeInstance implements Serializable { // Create Correlation Types for Accounts. int correlationTypeId = ADDITIONAL_TYPES_BASE_ID; for (Account.Type type : Account.Type.PREDEFINED_ACCOUNT_TYPES) { + // Skip Device account type - we dont want to correlate on those. // Skip Phone and Email accounts as there are already Correlation types defined for those. - if (type != Account.Type.EMAIL && type != Account.Type.PHONE) { + if (type != Account.Type.DEVICE && type != Account.Type.EMAIL && type != Account.Type.PHONE) { defaultCorrelationTypes.add(new CorrelationAttributeInstance.Type(correlationTypeId, type.getDisplayName(), type.getTypeName().toLowerCase() + "_acct", true, true)); //NON-NLS correlationTypeId++; } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index 04aa6fc16e..636c59886e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -27,6 +27,7 @@ import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoAccount.CentralRepoAccountType; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute; @@ -247,25 +248,29 @@ public class CorrelationAttributeUtil { // Get the account type from the artifact BlackboardAttribute accountTypeAttribute = acctArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE)); String accountTypeStr = accountTypeAttribute.getValueString(); + + // do not create any correlation attribute instance for a Device account + if (Account.Type.DEVICE.getTypeName().equalsIgnoreCase(accountTypeStr) == false) { - // Get the corresponding CentralRepoAccountType from the database. - CentralRepoAccountType crAccountType = CentralRepository.getInstance().getAccountTypeByName(accountTypeStr); + // Get the corresponding CentralRepoAccountType from the database. + CentralRepoAccountType crAccountType = CentralRepository.getInstance().getAccountTypeByName(accountTypeStr); - int corrTypeId = crAccountType.getCorrelationTypeId(); - CorrelationAttributeInstance.Type corrType = CentralRepository.getInstance().getCorrelationTypeById(corrTypeId); - - // Get the account identifier - BlackboardAttribute accountIdAttribute = acctArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ID)); - String accountIdStr = accountIdAttribute.getValueString(); - - // add/get the account and get its accountId. - CentralRepoAccount crAccount = CentralRepository.getInstance().getOrCreateAccount(crAccountType, accountIdStr); - - CorrelationAttributeInstance corrAttr = makeCorrAttr(acctArtifact, corrType, accountIdStr); - if (corrAttr != null) { - // set the account_id in correlation attribute - corrAttr.setAccountId(crAccount.getAccountId()); - corrAttrInstances.add(corrAttr); + int corrTypeId = crAccountType.getCorrelationTypeId(); + CorrelationAttributeInstance.Type corrType = CentralRepository.getInstance().getCorrelationTypeById(corrTypeId); + + // Get the account identifier + BlackboardAttribute accountIdAttribute = acctArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ID)); + String accountIdStr = accountIdAttribute.getValueString(); + + // add/get the account and get its accountId. + CentralRepoAccount crAccount = CentralRepository.getInstance().getOrCreateAccount(crAccountType, accountIdStr); + + CorrelationAttributeInstance corrAttr = makeCorrAttr(acctArtifact, corrType, accountIdStr); + if (corrAttr != null) { + // set the account_id in correlation attribute + corrAttr.setAccountId(crAccount.getAccountId()); + corrAttrInstances.add(corrAttr); + } } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java index 1232d708a6..6129ea45b6 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java @@ -193,7 +193,7 @@ public class RdbmsCentralRepoFactory { result = CentralRepoDbUtil.insertDefaultCorrelationTypes(conn) && CentralRepoDbUtil.insertDefaultOrganization(conn) && - insertDefaultAccountsTablesContent(conn); + RdbmsCentralRepoFactory.insertDefaultAccountsTablesContent(conn, selectedPlatform ); // @TODO: uncomment when ready to create/populate persona tables // && insertDefaultPersonaTablesContent(conn); @@ -766,33 +766,6 @@ public class RdbmsCentralRepoFactory { } - /** - * Inserts the default content in accounts related tables. - * - * @param conn Database connection to use. - * - * @return True if success, false otherwise. - */ - private boolean insertDefaultAccountsTablesContent(Connection conn) { - - try (Statement stmt = conn.createStatement()) { - // Populate the account_types table - for (Account.Type type : Account.Type.PREDEFINED_ACCOUNT_TYPES) { - int correlationTypeId = getCorrelationTypeIdForAccountType(conn, type); - if (correlationTypeId > 0) { - String sqlString = String.format("INSERT INTO account_types (type_name, display_name, correlation_type_id) VALUES ('%s', '%s', %d)" + getOnConflictDoNothingClause(selectedPlatform), - type.getTypeName(), type.getDisplayName(), correlationTypeId); - stmt.execute(sqlString); - } - } - } catch (SQLException ex) { - LOGGER.log(Level.SEVERE, String.format("Failed to populate default data in Accounts tables."), ex); - return false; - } - - return true; - } - /** * Inserts the default content in persona related tables. * @@ -838,11 +811,13 @@ public class RdbmsCentralRepoFactory { // Populate the account_types table for (Account.Type type : Account.Type.PREDEFINED_ACCOUNT_TYPES) { - int correlationTypeId = getCorrelationTypeIdForAccountType(conn, type); - if (correlationTypeId > 0) { - String sqlString = String.format("INSERT INTO account_types (type_name, display_name, correlation_type_id) VALUES ('%s', '%s', %d)" + getOnConflictDoNothingClause(selectedPlatform), - type.getTypeName(), type.getDisplayName(), correlationTypeId); - stmt.execute(sqlString); + if (type != Account.Type.DEVICE) { + int correlationTypeId = getCorrelationTypeIdForAccountType(conn, type); + if (correlationTypeId > 0) { + String sqlString = String.format("INSERT INTO account_types (type_name, display_name, correlation_type_id) VALUES ('%s', '%s', %d)" + getOnConflictDoNothingClause(selectedPlatform), + type.getTypeName(), type.getDisplayName(), correlationTypeId); + stmt.execute(sqlString); + } } } From 77cafd322b14d8027b53e2d96ee74cd95c8e8ed2 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 16 Mar 2020 07:45:41 -0400 Subject: [PATCH 07/41] suppressed warnings for BasicComboBoxRenderer usage --- .../optionspanel/EamDbSettingsDialog.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index 3b047b0e10..3322460b7d 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -68,6 +68,7 @@ public class EamDbSettingsDialog extends JDialog { private class DbChoiceRenderer extends BasicComboBoxRenderer { private static final long serialVersionUID = 1L; + @SuppressWarnings("rawtypes") public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { @@ -137,6 +138,14 @@ public class EamDbSettingsDialog extends JDialog { } + /** + * Sets the drowndown renderer so that an item is unselectable if inappropriate. + */ + @SuppressWarnings("unchecked") + private void setDropdownRenderer() { + cbDatabaseType.setRenderer(DB_CHOICE_RENDERER); + } + private void setupDbChoice(CentralRepoDbChoice initialMenuItem) { // setup initially selected item CentralRepoDbChoice toSelect = (initialMenuItem == null) ? @@ -144,10 +153,8 @@ public class EamDbSettingsDialog extends JDialog { manager.getSelectedDbChoice() : CentralRepoDbChoice.DB_CHOICES[0] : initialMenuItem; - - // set the renderer so item is unselectable if inappropriate - cbDatabaseType.setRenderer(DB_CHOICE_RENDERER); - + + setDropdownRenderer(); changeDbSelection(toSelect); } From d732e20839e7e8c10d4eda295487cd5e1b4ea3ee Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Mon, 16 Mar 2020 12:33:44 -0400 Subject: [PATCH 08/41] 6032 Move file name translation and make task --- .../datamodel/utils/FileNameTransTask.java | 61 ++++++++++++++++ .../utils/FileNameTranslator.java | 69 +++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100755 Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java create mode 100755 Core/src/org/sleuthkit/autopsy/texttranslation/utils/FileNameTranslator.java diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java b/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java new file mode 100755 index 0000000000..b11b7e2c64 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java @@ -0,0 +1,61 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.datamodel.utils; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import org.openide.nodes.AbstractNode; +import org.sleuthkit.autopsy.texttranslation.utils.FileNameTranslator; + +/** + * An AbstractNodePropertySheetTask that translates a file name for an + * AbstractNode's property sheet. + */ +public class FileNameTransTask extends AbstractNodePropertySheetTask { + + private final static String EVENT_SOURCE = FileNameTransTask.class.getName(); + private final static String PROPERTY_NAME = EVENT_SOURCE + ".TranslatedFileName"; + private final String fileName; + + public static String getPropertyName() { + return PROPERTY_NAME; + } + + /** + * Constructs an AbstractNodePropertySheetTask that translates a file name + * for an AbstractNode's property sheet. When the translation is complete, a + * PropertyChangeEvent will be fired to the node's PropertyChangeListener. + * Call getPropertyName() to identify the property. + * + * @param node The node. + * @param listener The node's PropertyChangeListener. + * @param fileName THe file name. + */ + public FileNameTransTask(String fileName, AbstractNode node, PropertyChangeListener listener) { + super(node, listener); + this.fileName = fileName; + } + + @Override + protected PropertyChangeEvent computePropertyValue(AbstractNode node) throws Exception { + String translatedFileName = FileNameTranslator.translate(fileName); + return new PropertyChangeEvent(EVENT_SOURCE, PROPERTY_NAME, fileName, "Foo"); + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/utils/FileNameTranslator.java b/Core/src/org/sleuthkit/autopsy/texttranslation/utils/FileNameTranslator.java new file mode 100755 index 0000000000..34a6506d02 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/utils/FileNameTranslator.java @@ -0,0 +1,69 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020-2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.texttranslation.utils; + +import org.apache.commons.io.FilenameUtils; +import org.sleuthkit.autopsy.texttranslation.NoServiceProviderException; +import org.sleuthkit.autopsy.texttranslation.TextTranslationService; +import org.sleuthkit.autopsy.texttranslation.TranslationException; + +/** + * A utility to translate file names. + */ +public class FileNameTranslator { + + /** + * Translates a file name using the configured machine translation service. + * + * @param fileName The file name. + * + * @return The translation of the file name. + * + * @throws NoServiceProviderException If machine translation is not + * configured. + * @throws TranslationException If there is an error doing the + * translation. + */ + public static String translate(String fileName) throws NoServiceProviderException, TranslationException { + +// //If already in complete English, don't translate. +// if (fileName.matches("^\\p{ASCII}+$")) { +// return ""; +// } + + TextTranslationService translator = TextTranslationService.getInstance(); + String baseName = FilenameUtils.getBaseName(fileName); + String translation = translator.translate(baseName); + if (!translation.isEmpty()) { + String extension = FilenameUtils.getExtension(fileName); + if (!extension.isEmpty()) { + String extensionDelimiter = (extension.isEmpty()) ? "" : "."; + translation += extensionDelimiter + extension; + } + } + return translation; + } + + /** + * Prevent instantiation of this utility class + */ + private FileNameTranslator() { + } + +} From 1085baf9cdf32763e9c0365161bd4c64084ecb44 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Tue, 17 Mar 2020 08:43:04 -0400 Subject: [PATCH 09/41] Extend file name translation to BlackboardArtifactNodes --- .../datamodel/AbstractAbstractFileNode.java | 44 +--- .../datamodel/BlackboardArtifactNode.java | 202 +++++++++++++----- .../autopsy/datamodel/Bundle.properties | 2 - .../datamodel/Bundle.properties-MERGED | 6 +- .../utils/AbstractNodePropertySheetTask.java | 16 +- .../datamodel/utils/FileNameTransTask.java | 2 +- .../utils/FileNameTranslator.java | 14 +- 7 files changed, 182 insertions(+), 104 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index 1d53e46ca6..e2043846fe 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.datamodel; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.lang.ref.WeakReference; +import java.text.MessageFormat; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; @@ -28,7 +29,6 @@ import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.stream.Collectors; -import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.openide.nodes.Sheet; @@ -66,6 +66,7 @@ import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; +import org.sleuthkit.autopsy.texttranslation.utils.FileNameTranslator; /** * An abstract node that encapsulates AbstractFile data @@ -94,15 +95,15 @@ public abstract class AbstractAbstractFileNode extends A IngestManager.getInstance().addIngestModuleEventListener(INGEST_MODULE_EVENTS_OF_INTEREST, weakPcl); } } - + try { //See JIRA-5971 //Attempt to cache file path during construction of this UI component. this.content.getUniquePath(); } catch (TskCoreException ex) { logger.log(Level.SEVERE, String.format("Failed attempt to cache the " - + "unique path of the abstract file instance. Name: %s (objID=%d)", - this.content.getName(), this.content.getId()), ex); + + "unique path of the abstract file instance. Name: %s (objID=%d)", + this.content.getName(), this.content.getId()), ex); } if (TextTranslationService.getInstance().hasProvider() && UserPreferences.displayTranslatedFileNames()) { @@ -490,39 +491,16 @@ public abstract class AbstractAbstractFileNode extends A } /** - * Translates this nodes content name. Doesn't attempt translation if the - * name is in english or if there is now translation service available. + * Translates the name of the file this node represents. An empty string + * will be returned if the translation fails for any reason. */ String getTranslatedFileName() { - //If already in complete English, don't translate. - if (content.getName().matches("^\\p{ASCII}+$")) { + try { + return FileNameTranslator.translate(content.getName()); + } catch (NoServiceProviderException | TranslationException ex) { + logger.log(Level.WARNING, MessageFormat.format("Error translating file name (objID={0}))", content.getId()), ex); return ""; } - TextTranslationService tts = TextTranslationService.getInstance(); - if (tts.hasProvider()) { - //Seperate out the base and ext from the contents file name. - String base = FilenameUtils.getBaseName(content.getName()); - try { - String translation = tts.translate(base); - String ext = FilenameUtils.getExtension(content.getName()); - - //If we have no extension, then we shouldn't add the . - String extensionDelimiter = (ext.isEmpty()) ? "" : "."; - - //Talk directly to this nodes pcl, fire an update when the translation - //is complete. - if (!translation.isEmpty()) { - return translation + extensionDelimiter + ext; - } - } catch (NoServiceProviderException noServiceEx) { - logger.log(Level.WARNING, "Translate unsuccessful because no TextTranslator " - + "implementation was provided.", noServiceEx.getMessage()); - } catch (TranslationException noTranslationEx) { - logger.log(Level.WARNING, "Could not successfully translate file name " - + content.getName(), noTranslationEx.getMessage()); - } - } - return ""; } /** diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index b4aafc2bcc..055d322203 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -76,6 +76,9 @@ import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; +import static org.sleuthkit.autopsy.datamodel.AbstractContentNode.NO_DESCR; +import org.sleuthkit.autopsy.texttranslation.TextTranslationService; +import org.sleuthkit.autopsy.datamodel.utils.FileNameTransTask; /** * A BlackboardArtifactNode is an AbstractNode implementation that can be used @@ -124,7 +127,7 @@ public class BlackboardArtifactNode extends AbstractContentNode> customProperties; - private final PropertyChangeListener appEventListener = new PropertyChangeListener() { + private final PropertyChangeListener listener = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { String eventType = evt.getPropertyName(); @@ -187,6 +190,17 @@ public class BlackboardArtifactNode extends AbstractContentNode(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(), scoData.getCountAndDescription().getRight(), scoData.getCountAndDescription().getLeft())); } + } else if (eventType.equals(FileNameTransTask.getPropertyName())) { + /* + * Replace the value of the Source File property with the + * translated name via setDisplayName (see note in createSheet), + * and put the untranslated name in the Original Name property. + * Also set the tooltip to the original name. + */ + setDisplayName(evt.getNewValue().toString()); + setShortDescription(evt.getOldValue().toString()); + updateSheet(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_srcFile_name(), Bundle.BlackboardArtifactNode_createSheet_srcFile_displayName(), NO_DESCR, (String) evt.getNewValue())); + //updateSheet(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_srcFile_origName(), Bundle.BlackboardArtifactNode_createSheet_srcFile_origDisplayName(), NO_DESCR, (String) evt.getOldValue())); } } }; @@ -198,7 +212,7 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.srcFile.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.srcFile.displayName"), + sheetSet.put(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_srcFile_name(), + Bundle.BlackboardArtifactNode_createSheet_srcFile_displayName(), NO_DESCR, this.getSourceName())); + if (TextTranslationService.getInstance().hasProvider() && UserPreferences.displayTranslatedFileNames()) { + /* + * If machine translation is configured, add the original name of + * the of the source content of the artifact represented by this + * node to the sheet. + */ + sheetSet.put(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_srcFile_origName(), + Bundle.BlackboardArtifactNode_createSheet_srcFile_origDisplayName(), + NO_DESCR, + "")); + if (srcContent != null) { + new FileNameTransTask(srcContent.getName(), this, listener).submit(); + } + } + if (!UserPreferences.getHideSCOColumns()) { /* * Add S(core), C(omments), and O(ther occurences) columns to the @@ -414,14 +463,20 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactType.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactType.displayName"), - NO_DESCR, - associatedArtifact.getDisplayName())); - sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactDetails.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactDetails.displayName"), - NO_DESCR, - associatedArtifact.getShortDescription())); + sheetSet + .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.artifactType.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.artifactType.displayName"), + NO_DESCR, + associatedArtifact.getDisplayName())); + sheetSet + .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.artifactDetails.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.artifactDetails.displayName"), + NO_DESCR, + associatedArtifact.getShortDescription())); } } catch (TskCoreException | NoCurrentCaseException ex) { logger.log(Level.SEVERE, MessageFormat.format("Error getting associated artifact of TSK_INTERESTING_ARTIFACT_HIT artifact (objID={0}))", artifact.getId()), ex); //NON-NLS @@ -465,17 +520,23 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.ext.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.ext.displayName"), + sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.ext.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.ext.displayName"), NO_DESCR, ext)); - sheetSet.put(new NodeProperty<>( - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.mimeType.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.mimeType.displayName"), - NO_DESCR, - actualMimeType)); + sheetSet + .put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.mimeType.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.mimeType.displayName"), + NO_DESCR, + actualMimeType)); } /* @@ -489,13 +550,16 @@ public class BlackboardArtifactNode extends AbstractContentNode( - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.filePath.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.filePath.displayName"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.filePath.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.filePath.displayName"), NO_DESCR, sourcePath)); } @@ -507,26 +571,41 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.displayName"), - "", - file == null ? "" : ContentUtils.getStringTime(file.getMtime(), file))); - sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileChangedTime.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileChangedTime.displayName"), - "", - file == null ? "" : ContentUtils.getStringTime(file.getCtime(), file))); - sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileAccessedTime.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileAccessedTime.displayName"), - "", - file == null ? "" : ContentUtils.getStringTime(file.getAtime(), file))); - sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileCreatedTime.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileCreatedTime.displayName"), - "", - file == null ? "" : ContentUtils.getStringTime(file.getCrtime(), file))); - sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.displayName"), - "", - file == null ? "" : file.getSize())); + sheetSet + .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileModifiedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileModifiedTime.displayName"), + "", + file == null ? "" : ContentUtils.getStringTime(file.getMtime(), file))); + sheetSet + .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileChangedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileChangedTime.displayName"), + "", + file == null ? "" : ContentUtils.getStringTime(file.getCtime(), file))); + sheetSet + .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileAccessedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileAccessedTime.displayName"), + "", + file == null ? "" : ContentUtils.getStringTime(file.getAtime(), file))); + sheetSet + .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileCreatedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileCreatedTime.displayName"), + "", + file == null ? "" : ContentUtils.getStringTime(file.getCrtime(), file))); + sheetSet + .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileSize.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "ContentTagNode.createSheet.fileSize.displayName"), + "", + file == null ? "" : file.getSize())); sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_artifactMD5_name(), Bundle.BlackboardArtifactNode_createSheet_artifactMD5_displayName(), "", @@ -544,13 +623,16 @@ public class BlackboardArtifactNode extends AbstractContentNode( - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.dataSrc.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.dataSrc.displayName"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.dataSrc.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.dataSrc.displayName"), NO_DESCR, dataSourceStr)); } @@ -570,17 +652,23 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.fileSize.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.fileSize.displayName"), + sheetSet.put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.fileSize.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.fileSize.displayName"), NO_DESCR, size)); - sheetSet.put(new NodeProperty<>( - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.path.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.path.displayName"), - NO_DESCR, - path)); + sheetSet + .put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.path.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, + "BlackboardArtifactNode.createSheet.path.displayName"), + NO_DESCR, + path)); } return sheet; @@ -1036,8 +1124,8 @@ public class BlackboardArtifactNode extends AbstractContentNode impl * @return The Future of the task, may be used for task cancellation by * calling Future.cancel(true). */ - public static Future submitTask(AbstractNodePropertySheetTask task) { + private static Future submitTask(AbstractNodePropertySheetTask task) { return executor.submit(task); } @@ -104,12 +104,22 @@ public abstract class AbstractNodePropertySheetTask impl * * @param node The AbstractNode. * - * @return The result of the computation as a PropertyChangeEvent. + * @return The result of the computation as a PropertyChangeEvent, may be + * null. */ protected abstract PropertyChangeEvent computePropertyValue(T node) throws Exception; + /** + * Submits this task to the ExecutorService for the thread pool. + * + * @return The task's Future from the ExecutorService. + */ + public final Future submit() { + return submitTask(this); + } + @Override - final public void run() { + public final void run() { try { T node = this.weakNodeRef.get(); PropertyChangeListener listener = this.weakListenerRef.get(); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java b/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java index b11b7e2c64..88ccac2d2f 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java @@ -55,7 +55,7 @@ public class FileNameTransTask extends AbstractNodePropertySheetTask Date: Tue, 17 Mar 2020 09:44:15 -0400 Subject: [PATCH 10/41] Update cachelocation.py Change GPS_TRACKPOINT to GPS_BOOKMARK. Change how cache file is processed and read. --- .../android/cachelocation.py | 73 +++++-------------- 1 file changed, 18 insertions(+), 55 deletions(-) diff --git a/InternalPythonModules/android/cachelocation.py b/InternalPythonModules/android/cachelocation.py index 1fb162a817..3697fb44b0 100644 --- a/InternalPythonModules/android/cachelocation.py +++ b/InternalPythonModules/android/cachelocation.py @@ -41,6 +41,7 @@ from org.sleuthkit.datamodel import TskCoreException import traceback import general +import struct """ Parses cache files that Android maintains for Wifi and cell towers. Adds GPS points to blackboard. @@ -74,60 +75,24 @@ class CacheLocationAnalyzer(general.AndroidComponentAnalyzer): def __findGeoLocationsInFile(self, file, abstractFile): - tempBytes = bytearray([0] * 2) # will temporarily hold bytes to be converted into the correct data types - try: - inputStream = FileInputStream(file) - - inputStream.read(tempBytes) # version - - tempBytes = bytearray([0] * 2) - inputStream.read(tempBytes) # number of location entries - - iterations = BigInteger(tempBytes).intValue() - - for i in range(iterations): # loop through every entry - tempBytes = bytearray([0] * 2) - inputStream.read(tempBytes) - - tempBytes = bytearray([0]) - inputStream.read(tempBytes) - - while BigInteger(tempBytes).intValue() != 0: # pass through non important values until the start of accuracy(around 7-10 bytes) - if 0 > inputStream.read(tempBytes): - break # we've passed the end of the file, so stop - - tempBytes = bytearray([0] * 3) - inputStream.read(tempBytes) - if BigInteger(tempBytes).intValue() <= 0: # This refers to a location that could not be calculated - tempBytes = bytearray([0] * 28) # read rest of the row's bytes - inputStream.read(tempBytes) - continue - accuracy = "" + BigInteger(tempBytes).intValue() - - tempBytes = bytearray([0] * 4) - inputStream.read(tempBytes) - confidence = "" + BigInteger(tempBytes).intValue() - - tempBytes = bytearray([0] * 8) - inputStream.read(tempBytes) - latitude = CacheLocationAnalyzer.toDouble(bytes) - - tempBytes = bytearray([0] * 8) - inputStream.read(tempBytes) - longitude = CacheLocationAnalyzer.toDouble(bytes) - - tempBytes = bytearray([0] * 8) - inputStream.read(tempBytes) - timestamp = BigInteger(tempBytes).longValue() / 1000 + # code to parse the cache.wifi and cache.cell taken from https://forensics.spreitzenbarth.de/2011/10/28/decoding-cache-cell-and-cache-wifi-files/ + cacheFile = open(str(file), 'rb') + (version, entries) = struct.unpack('>hh', cacheFile.read(4)) + i = 0 + while i < entries: + key = cacheFile.read(struct.unpack('>h', cacheFile.read(2))[0]) + (accuracy, confidence, latitude, longitude, readtime) = struct.unpack('>iiddQ', cacheFile.read(32)) + timestamp = readtime/1000 + i = i + 1 attributes = ArrayList() - artifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE, AndroidAnalyzer.MODULE_NAME, latitude)) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE, AndroidAnalyzer.MODULE_NAME, longitude)) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, AndroidModuleFactorymodule.Name, timestamp)) - attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, AndroidAnalyzer.MODULE_NAME, - file.getName() + "Location History")) + artifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK) + attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE, general.MODULE_NAME, latitude)) + attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE, general.MODULE_NAME, longitude)) + attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, general.MODULE_NAME, timestamp)) + attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, general.MODULE_NAME, + abstractFile.getName() + " Location History")) artifact.addAttributes(attributes) #Not storing these for now. @@ -136,15 +101,13 @@ class CacheLocationAnalyzer(general.AndroidComponentAnalyzer): try: # index the artifact for keyword search blackboard = Case.getCurrentCase().getSleuthkitCase().getBlackboard() - blackboard.postArtifact(artifact, MODULE_NAME) + blackboard.postArtifact(artifact, general.MODULE_NAME) except Blackboard.BlackboardException as ex: self._logger.log(Level.SEVERE, "Unable to index blackboard artifact " + str(artifact.getArtifactID()), ex) self._logger.log(Level.SEVERE, traceback.format_exc()) MessageNotifyUtil.Notify.error("Failed to index GPS trackpoint artifact for keyword search.", artifact.getDisplayName()) + cacheFile.close() - except SQLException as ex: - # Unable to execute Cached GPS locations SQL query against database. - pass except Exception as ex: self._logger.log(Level.SEVERE, "Error parsing Cached GPS locations to blackboard", ex) self._logger.log(Level.SEVERE, traceback.format_exc()) From da735c673e88667f532f0b1a77bef51a7b354f93 Mon Sep 17 00:00:00 2001 From: Mark McKinnon Date: Tue, 17 Mar 2020 10:10:56 -0400 Subject: [PATCH 11/41] Update browserlocation.py Change GPS_Trackpoint to GPS_Bookmark --- InternalPythonModules/android/browserlocation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/InternalPythonModules/android/browserlocation.py b/InternalPythonModules/android/browserlocation.py index 84c2a601e7..c202c36d2a 100644 --- a/InternalPythonModules/android/browserlocation.py +++ b/InternalPythonModules/android/browserlocation.py @@ -95,7 +95,7 @@ class BrowserLocationAnalyzer(general.AndroidComponentAnalyzer): longitude = Double.valueOf(resultSet.getString("longitude")) attributes = ArrayList() - artifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACKPOINT) + artifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_BOOKMARK) attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE, general.MODULE_NAME, latitude)) attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE, general.MODULE_NAME, longitude)) attributes.add(BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, general.MODULE_NAME, timestamp)) From 04638faa85268212992ad7917ce346f76df40dca Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 17 Mar 2020 14:57:11 -0400 Subject: [PATCH 12/41] updated to use TypedBasicComboBoxRenderer --- .../optionspanel/EamDbSettingsDialog.java | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index 3322460b7d..09b98a7337 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -38,7 +38,6 @@ import javax.swing.SwingUtilities; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.filechooser.FileFilter; -import javax.swing.plaf.basic.BasicComboBoxRenderer; import org.netbeans.spi.options.OptionsPanelController; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; @@ -65,19 +64,17 @@ public class EamDbSettingsDialog extends JDialog { /** * This class handles displaying and rendering drop down menu for database choices in central repo. */ - private class DbChoiceRenderer extends BasicComboBoxRenderer { + private class DbChoiceRenderer extends TypedBasicComboBoxRenderer { private static final long serialVersionUID = 1L; - @SuppressWarnings("rawtypes") - public Component getListCellRendererComponent(JList list, Object value, + public Component getListCellRendererComponent( + JList list, CentralRepoDbChoice value, int index, boolean isSelected, boolean cellHasFocus) { - CentralRepoDbChoice item = (CentralRepoDbChoice) value; - // disable cell if it is the db connection from multi user settings // and that option is not enabled in multi user settings - setText(item.getTitle()); - setEnabled(isDbChoiceSelectable(item)); + setText(value.getTitle()); + setEnabled(isDbChoiceSelectable(value)); return this; } } @@ -136,15 +133,7 @@ public class EamDbSettingsDialog extends JDialog { valid(); display(); } - - - /** - * Sets the drowndown renderer so that an item is unselectable if inappropriate. - */ - @SuppressWarnings("unchecked") - private void setDropdownRenderer() { - cbDatabaseType.setRenderer(DB_CHOICE_RENDERER); - } + private void setupDbChoice(CentralRepoDbChoice initialMenuItem) { // setup initially selected item @@ -154,7 +143,7 @@ public class EamDbSettingsDialog extends JDialog { CentralRepoDbChoice.DB_CHOICES[0] : initialMenuItem; - setDropdownRenderer(); + cbDatabaseType.setRenderer(DB_CHOICE_RENDERER); changeDbSelection(toSelect); } From 87b6398cfc6ce5396e0bfa4706493fc80b52559f Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 17 Mar 2020 14:57:20 -0400 Subject: [PATCH 13/41] updated to use TypedBasicComboBoxRenderer --- .../TypedBasicComboBoxRenderer.java | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/TypedBasicComboBoxRenderer.java diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/TypedBasicComboBoxRenderer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/TypedBasicComboBoxRenderer.java new file mode 100644 index 0000000000..8788651f73 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/TypedBasicComboBoxRenderer.java @@ -0,0 +1,71 @@ +/* + * Central Repository + * + * Copyright 2015-2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.centralrepository.optionspanel; + +import java.awt.Dimension; +import java.io.Serializable; +import javax.swing.JLabel; +import javax.swing.ListCellRenderer; +import javax.swing.border.Border; +import javax.swing.border.EmptyBorder; + +/** + * This class implements the same behavior as the BasicComboBoxRenderer while + * providing type safety. + * @param The object type that will be used in the combo box. + */ +public abstract class TypedBasicComboBoxRenderer extends JLabel +implements ListCellRenderer, Serializable { + + protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1); + private final static Border SAFE_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1); + + /** + * The main constructor for this class. + */ + public TypedBasicComboBoxRenderer() { + super(); + setOpaque(true); + setBorder(getNoFocusBorder()); + } + + private static Border getNoFocusBorder() { + if (System.getSecurityManager() != null) { + return SAFE_NO_FOCUS_BORDER; + } else { + return noFocusBorder; + } + } + + @Override + public Dimension getPreferredSize() { + Dimension size; + + if ((this.getText() == null) || (this.getText().equals( "" ))) { + setText( " " ); + size = super.getPreferredSize(); + setText( "" ); + } + else { + size = super.getPreferredSize(); + } + + return size; + } +} From 291d778ee2a96bf2d36e15f08ebe50650ed719f7 Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Tue, 17 Mar 2020 16:16:04 -0400 Subject: [PATCH 14/41] 6151: Do not add account_id column to non-account correlation attribute instance tables --- .../CentralRepoDbUpgrader13To14.java | 25 ++++++------ .../datamodel/CentralRepoDbUtil.java | 13 +++++++ .../datamodel/RdbmsCentralRepo.java | 31 ++++++++++----- .../datamodel/RdbmsCentralRepoFactory.java | 38 +++++++++++++++++-- 4 files changed, 82 insertions(+), 25 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java index 9d6473055e..dbd1e77da4 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java @@ -51,7 +51,7 @@ public class CentralRepoDbUpgrader13To14 implements CentralRepoDbUpgrader { if (type.getId() >= CorrelationAttributeInstance.ADDITIONAL_TYPES_BASE_ID) { // these are new Correlation types - new tables need to be created - statement.execute(String.format(RdbmsCentralRepoFactory.getCreateArtifactInstancesTableTemplate(selectedPlatform), instance_type_dbname, instance_type_dbname)); + statement.execute(String.format(RdbmsCentralRepoFactory.getCreateAccountInstancesTableTemplate(selectedPlatform), instance_type_dbname, instance_type_dbname)); statement.execute(String.format(RdbmsCentralRepoFactory.getAddCaseIdIndexTemplate(), instance_type_dbname, instance_type_dbname)); statement.execute(String.format(RdbmsCentralRepoFactory.getAddDataSourceIdIndexTemplate(), instance_type_dbname, instance_type_dbname)); statement.execute(String.format(RdbmsCentralRepoFactory.getAddValueIndexTemplate(), instance_type_dbname, instance_type_dbname)); @@ -61,18 +61,19 @@ public class CentralRepoDbUpgrader13To14 implements CentralRepoDbUpgrader { // add new correlation type CentralRepoDbUtil.insertCorrelationType(connection, type); - } else { - - // Alter the existing X_Instance tables to add account_id column - String sqlStr = String.format(getAlterArtifactInstancesAddAccountIdTemplate(selectedPlatform), instance_type_dbname); - statement.execute(sqlStr); - - // SQLite does NOT allow adding a constraint with Alter Table statement. - // The alternative would be to create new tables, copy all data over, and delete old tables - potentially a time consuming process. - // We decided to not add this constraint for SQLite, since there likely aren't many users using SQLite based Central Repo. - if (selectedPlatform == CentralRepoPlatforms.POSTGRESQL) { - sqlStr = String.format(getAlterArtifactInstancesAddAccountIdConstraintTemplate(), instance_type_dbname); + } else { // existing attributes + // Alter the existing _instance tables for Phone and Email attributes to add account_id column + if (type.getId() == CorrelationAttributeInstance.EMAIL_TYPE_ID || type.getId() == CorrelationAttributeInstance.PHONE_TYPE_ID) { + String sqlStr = String.format(getAlterArtifactInstancesAddAccountIdTemplate(selectedPlatform), instance_type_dbname); statement.execute(sqlStr); + + // SQLite does NOT allow adding a constraint with Alter Table statement. + // The alternative would be to create new tables, copy all data over, and delete old tables - potentially a time consuming process. + // We decided to not add this constraint for SQLite, since there likely aren't many users using SQLite based Central Repo. + if (selectedPlatform == CentralRepoPlatforms.POSTGRESQL) { + sqlStr = String.format(getAlterArtifactInstancesAddAccountIdConstraintTemplate(), instance_type_dbname); + statement.execute(sqlStr); + } } } } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUtil.java index 826c315c02..69ea8d4e05 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUtil.java @@ -325,4 +325,17 @@ public class CentralRepoDbUtil { closeStatement(preparedStatement); } + /** + * Checks if the given correlation attribute type has an account behind it. + * + * @param type Correlation type to check. + * + * @return True If the specified correlation type has an account. + */ + static boolean correlationAttribHasAnAccount(CorrelationAttributeInstance.Type type) { + return (type.getId() >= CorrelationAttributeInstance.ADDITIONAL_TYPES_BASE_ID) + || type.getId() == CorrelationAttributeInstance.PHONE_TYPE_ID + || type.getId() == CorrelationAttributeInstance.EMAIL_TYPE_ID; + } + } diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java index 63f8e2f13a..148513f40c 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepo.java @@ -1002,18 +1002,26 @@ abstract class RdbmsCentralRepo implements CentralRepository { public void addArtifactInstance(CorrelationAttributeInstance eamArtifact) throws CentralRepoException { checkAddArtifactInstanceNulls(eamArtifact); - - - - // @@@ We should cache the case and data source IDs in memory String tableName = CentralRepoDbUtil.correlationTypeToInstanceTableName(eamArtifact.getCorrelationType()); - String sql - = "INSERT INTO " + boolean artifactHasAnAccount = CentralRepoDbUtil.correlationAttribHasAnAccount(eamArtifact.getCorrelationType()); + + String sql; + // _instance table for accounts have an additional account_id column + if (artifactHasAnAccount) { + sql = "INSERT INTO " + tableName + "(case_id, data_source_id, value, file_path, known_status, comment, file_obj_id, account_id) " + "VALUES (?, ?, ?, ?, ?, ?, ?, ?) " + getConflictClause(); + } + else { + sql = "INSERT INTO " + + tableName + + "(case_id, data_source_id, value, file_path, known_status, comment, file_obj_id) " + + "VALUES (?, ?, ?, ?, ?, ?, ?) " + + getConflictClause(); + } try (Connection conn = connect(); PreparedStatement preparedStatement = conn.prepareStatement(sql);) { @@ -1032,10 +1040,13 @@ abstract class RdbmsCentralRepo implements CentralRepository { } preparedStatement.setLong(7, eamArtifact.getFileObjectId()); - if (eamArtifact.getAccountId() >= 0) { - preparedStatement.setLong(8, eamArtifact.getAccountId()); - } else { - preparedStatement.setNull(8, Types.INTEGER); + // set in the accountId only for artifacts that represent accounts + if (artifactHasAnAccount) { + if (eamArtifact.getAccountId() >= 0) { + preparedStatement.setLong(8, eamArtifact.getAccountId()); + } else { + preparedStatement.setNull(8, Types.INTEGER); + } } preparedStatement.executeUpdate(); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java index 1232d708a6..d50d344a5e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java @@ -83,6 +83,7 @@ public class RdbmsCentralRepoFactory { public boolean initializeDatabaseSchema() { String createArtifactInstancesTableTemplate = getCreateArtifactInstancesTableTemplate(selectedPlatform); + String createAccountInstancesTableTemplate = getCreateAccountInstancesTableTemplate(selectedPlatform); String instancesCaseIdIdx = getAddCaseIdIndexTemplate(); String instancesDatasourceIdIdx = getAddDataSourceIdIndexTemplate(); @@ -147,7 +148,13 @@ public class RdbmsCentralRepoFactory { reference_type_dbname = CentralRepoDbUtil.correlationTypeToReferenceTableName(type); instance_type_dbname = CentralRepoDbUtil.correlationTypeToInstanceTableName(type); - stmt.execute(String.format(createArtifactInstancesTableTemplate, instance_type_dbname, instance_type_dbname)); + // use the correct create table template, based on whether the attribute type represents an account or not. + String createTableTemplate = (CentralRepoDbUtil.correlationAttribHasAnAccount(type)) + ? createAccountInstancesTableTemplate + : createArtifactInstancesTableTemplate; + + stmt.execute(String.format(createTableTemplate, instance_type_dbname, instance_type_dbname)); + stmt.execute(String.format(instancesCaseIdIdx, instance_type_dbname, instance_type_dbname)); stmt.execute(String.format(instancesDatasourceIdIdx, instance_type_dbname, instance_type_dbname)); stmt.execute(String.format(instancesValueIdx, instance_type_dbname, instance_type_dbname)); @@ -357,7 +364,7 @@ public class RdbmsCentralRepoFactory { + ")"; } /** - * Get the template String for creating a new _instances table in a Sqlite + * Get the template String for creating a new _instances table for non account artifacts in * central repository. %s will exist in the template where the name of the * new table will be added. * @@ -365,6 +372,31 @@ public class RdbmsCentralRepoFactory { */ static String getCreateArtifactInstancesTableTemplate(CentralRepoPlatforms selectedPlatform) { // Each "%s" will be replaced with the relevant TYPE_instances table name. + + return "CREATE TABLE IF NOT EXISTS %s (" + + getNumericPrimaryKeyClause("id", selectedPlatform) + + "case_id integer NOT NULL," + + "data_source_id integer NOT NULL," + + "value text NOT NULL," + + "file_path text NOT NULL," + + "known_status integer NOT NULL," + + "comment text," + + "file_obj_id " + getBigIntType(selectedPlatform) + " ," + + "CONSTRAINT %s_multi_unique UNIQUE(data_source_id, value, file_path)" + getOnConflictIgnoreClause(selectedPlatform) + "," + + "foreign key (case_id) references cases(id) ON UPDATE SET NULL ON DELETE SET NULL," + + "foreign key (data_source_id) references data_sources(id) ON UPDATE SET NULL ON DELETE SET NULL)"; + } + + /** + * Get the template String for creating a new _instances table for Accounts in + * central repository. %s will exist in the template where the name of the + * new table will be added. + * + * @return a String which is a template for creating a _instances table + */ + static String getCreateAccountInstancesTableTemplate(CentralRepoPlatforms selectedPlatform) { + // Each "%s" will be replaced with the relevant TYPE_instances table name. + return "CREATE TABLE IF NOT EXISTS %s (" + getNumericPrimaryKeyClause("id", selectedPlatform) + "case_id integer NOT NULL," @@ -380,7 +412,7 @@ public class RdbmsCentralRepoFactory { + "foreign key (case_id) references cases(id) ON UPDATE SET NULL ON DELETE SET NULL," + "foreign key (data_source_id) references data_sources(id) ON UPDATE SET NULL ON DELETE SET NULL)"; } - + /** * Get the statement String for creating a new data_sources table in a * Sqlite central repository. From 6b2f81134a9fcc4392e3e60e4db597d6cfe540f9 Mon Sep 17 00:00:00 2001 From: Raman Arora Date: Tue, 17 Mar 2020 18:48:29 -0400 Subject: [PATCH 15/41] Address Codacy comment. --- .../CentralRepoDbUpgrader13To14.java | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java index dbd1e77da4..0acfd34ea5 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoDbUpgrader13To14.java @@ -61,19 +61,17 @@ public class CentralRepoDbUpgrader13To14 implements CentralRepoDbUpgrader { // add new correlation type CentralRepoDbUtil.insertCorrelationType(connection, type); - } else { // existing attributes + } else if (type.getId() == CorrelationAttributeInstance.EMAIL_TYPE_ID || type.getId() == CorrelationAttributeInstance.PHONE_TYPE_ID) { // Alter the existing _instance tables for Phone and Email attributes to add account_id column - if (type.getId() == CorrelationAttributeInstance.EMAIL_TYPE_ID || type.getId() == CorrelationAttributeInstance.PHONE_TYPE_ID) { - String sqlStr = String.format(getAlterArtifactInstancesAddAccountIdTemplate(selectedPlatform), instance_type_dbname); - statement.execute(sqlStr); + String sqlStr = String.format(getAlterArtifactInstancesAddAccountIdTemplate(selectedPlatform), instance_type_dbname); + statement.execute(sqlStr); - // SQLite does NOT allow adding a constraint with Alter Table statement. - // The alternative would be to create new tables, copy all data over, and delete old tables - potentially a time consuming process. - // We decided to not add this constraint for SQLite, since there likely aren't many users using SQLite based Central Repo. - if (selectedPlatform == CentralRepoPlatforms.POSTGRESQL) { - sqlStr = String.format(getAlterArtifactInstancesAddAccountIdConstraintTemplate(), instance_type_dbname); - statement.execute(sqlStr); - } + // SQLite does NOT allow adding a constraint with Alter Table statement. + // The alternative would be to create new tables, copy all data over, and delete old tables - potentially a time consuming process. + // We decided to not add this constraint for SQLite, since there likely aren't many users using SQLite based Central Repo. + if (selectedPlatform == CentralRepoPlatforms.POSTGRESQL) { + sqlStr = String.format(getAlterArtifactInstancesAddAccountIdConstraintTemplate(), instance_type_dbname); + statement.execute(sqlStr); } } } From 8fdb645124e0b0233668f9d2e74221204da10d96 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Wed, 18 Mar 2020 09:36:46 -0400 Subject: [PATCH 16/41] Remove X-log from file discovery to focus on user created docs --- Core/src/org/sleuthkit/autopsy/filequery/FileSearchData.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileSearchData.java b/Core/src/org/sleuthkit/autopsy/filequery/FileSearchData.java index d86d470102..32a2cf19cb 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileSearchData.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileSearchData.java @@ -273,7 +273,6 @@ final class FileSearchData { = new ImmutableSet.Builder() .add("text/html", //NON-NLS "text/csv", //NON-NLS - "text/x-log", //NON-NLS "application/rtf", //NON-NLS "application/pdf", //NON-NLS "application/xhtml+xml", //NON-NLS From 906fc50a087cf5fe944b452ee94e68e1cf5a744e Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 18 Mar 2020 11:02:53 -0400 Subject: [PATCH 17/41] using list renderer --- .../optionspanel/EamDbSettingsDialog.java | 5 +- .../TypedBasicComboBoxRenderer.java | 71 ------------------- 2 files changed, 4 insertions(+), 72 deletions(-) delete mode 100644 Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/TypedBasicComboBoxRenderer.java diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index 09b98a7337..fda6935999 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -24,6 +24,7 @@ import java.awt.Cursor; import java.awt.HeadlessException; import java.io.File; import java.io.IOException; +import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -31,9 +32,11 @@ import java.util.logging.Level; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JFrame; +import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JTextField; +import javax.swing.ListCellRenderer; import javax.swing.SwingUtilities; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; @@ -64,7 +67,7 @@ public class EamDbSettingsDialog extends JDialog { /** * This class handles displaying and rendering drop down menu for database choices in central repo. */ - private class DbChoiceRenderer extends TypedBasicComboBoxRenderer { + private class DbChoiceRenderer extends JLabel implements ListCellRenderer, Serializable { private static final long serialVersionUID = 1L; public Component getListCellRendererComponent( diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/TypedBasicComboBoxRenderer.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/TypedBasicComboBoxRenderer.java deleted file mode 100644 index 8788651f73..0000000000 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/TypedBasicComboBoxRenderer.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Central Repository - * - * Copyright 2015-2020 Basis Technology Corp. - * Contact: carrier sleuthkit org - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.sleuthkit.autopsy.centralrepository.optionspanel; - -import java.awt.Dimension; -import java.io.Serializable; -import javax.swing.JLabel; -import javax.swing.ListCellRenderer; -import javax.swing.border.Border; -import javax.swing.border.EmptyBorder; - -/** - * This class implements the same behavior as the BasicComboBoxRenderer while - * providing type safety. - * @param The object type that will be used in the combo box. - */ -public abstract class TypedBasicComboBoxRenderer extends JLabel -implements ListCellRenderer, Serializable { - - protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1); - private final static Border SAFE_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1); - - /** - * The main constructor for this class. - */ - public TypedBasicComboBoxRenderer() { - super(); - setOpaque(true); - setBorder(getNoFocusBorder()); - } - - private static Border getNoFocusBorder() { - if (System.getSecurityManager() != null) { - return SAFE_NO_FOCUS_BORDER; - } else { - return noFocusBorder; - } - } - - @Override - public Dimension getPreferredSize() { - Dimension size; - - if ((this.getText() == null) || (this.getText().equals( "" ))) { - setText( " " ); - size = super.getPreferredSize(); - setText( "" ); - } - else { - size = super.getPreferredSize(); - } - - return size; - } -} From 065a7313c399f10a27a143e5c6f840697c40abc3 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 18 Mar 2020 12:01:35 -0400 Subject: [PATCH 18/41] added override annotation --- .../centralrepository/optionspanel/EamDbSettingsDialog.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java index fda6935999..4c70d6aa5c 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/EamDbSettingsDialog.java @@ -70,6 +70,7 @@ public class EamDbSettingsDialog extends JDialog { private class DbChoiceRenderer extends JLabel implements ListCellRenderer, Serializable { private static final long serialVersionUID = 1L; + @Override public Component getListCellRendererComponent( JList list, CentralRepoDbChoice value, int index, boolean isSelected, boolean cellHasFocus) { From aa6ed94b14f5e95b2f543eb0e220865ef73f3dd1 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Wed, 18 Mar 2020 14:07:34 -0400 Subject: [PATCH 19/41] Implemented a safer and correct way of calling Gst.init() --- .../contentviewers/MediaPlayerPanel.java | 21 ++---- .../contentviewers/utils/GstLoader.java | 72 +++++++++++++++++++ 2 files changed, 78 insertions(+), 15 deletions(-) create mode 100755 Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java index d2d8ace001..53bae5638d 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java @@ -74,6 +74,8 @@ import org.freedesktop.gstreamer.Format; import org.freedesktop.gstreamer.GstException; import org.freedesktop.gstreamer.event.SeekFlags; import org.freedesktop.gstreamer.event.SeekType; +import org.sleuthkit.autopsy.contentviewers.utils.GstLoader; +import org.sleuthkit.autopsy.contentviewers.utils.GstLoader.GstStatus; /** * This is a video player that is part of the Media View layered pane. It uses @@ -540,23 +542,12 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie if (this.isCancelled()) { return; } - - // Setting the following property causes the GST - // Java bindings to call dispose() on the GST - // service thread instead of running it in the GST - // Native Object Reaper thread. - System.setProperty("glib.reapOnEDT", "true"); - - // Initialize Gstreamer. It is safe to call this for every file. - // It was moved here from the constructor because having it happen - // earlier resulted in crashes on Linux. See JIRA-5888. - Gst.init(); - - if (!Gst.isInitialized()) { - logger.log(Level.INFO, "GStreamer is not initialized."); //NON-NLS + + GstStatus loadStatus = GstLoader.tryLoad(); + if(loadStatus == GstStatus.FAILURE) { return; } - + Gst.getExecutor().submit(() -> { //Video is ready for playback. Create new components gstPlayBin = new PlayBin("VideoPlayer", tempFile.toURI()); diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java b/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java new file mode 100755 index 0000000000..d04e0f4ac0 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java @@ -0,0 +1,72 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.sleuthkit.autopsy.contentviewers.utils; + +import java.util.logging.Level; +import org.freedesktop.gstreamer.Gst; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; + +/** + * + * @author dsmyda + */ +public class GstLoader { + + private static final Logger logger = Logger.getLogger(GstLoader.class.getName()); + private static GstStatus status; + + /** + * Attempts to load the gstreamer bindings. Only one attempt will be + * performed per Autopsy process. Clients should not attempt to interact + * with the gstreamer bindings unless the load was successful. + * + * @return Status - SUCCESS or FAILURE + */ + public synchronized static GstStatus tryLoad() { + // Null is our 'unknown' status. Prior to the first call, the status + // is unknown. + if (status != null) { + return status; + } + + try { + // Setting the following property causes the GST + // Java bindings to call dispose() on the GST + // service thread instead of running it in the GST + // Native Object Reaper thread. + System.setProperty("glib.reapOnEDT", "true"); + Gst.init(); + status = GstStatus.SUCCESS; + } catch (Throwable ex) { + status = GstStatus.FAILURE; + MessageNotifyUtil.Message.error("A problem was encountered with" + + "the video playback service. Video playback will" + + " be disabled for the remainder of the session."); + logger.log(Level.WARNING, "Failed to load gsteamer bindings", ex); + } + + return status; + } + + public enum GstStatus { + SUCCESS, FAILURE + } +} From 10e16281ed0904206b0e701c8a0a3985ed8c3a07 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 18 Mar 2020 16:31:04 -0400 Subject: [PATCH 20/41] don't raise warning if settings not located --- .../CentralRepoPostgresSettingsUtil.java | 64 +++++++++++-------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java index 3f75e9e183..86f929ba0e 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CentralRepoPostgresSettingsUtil.java @@ -63,9 +63,21 @@ public class CentralRepoPostgresSettingsUtil { private CentralRepoPostgresSettingsUtil() {} - private void logException(TryHandler handler) { + /** + * Uses setter object to set a value as specified by 'value'. In the event that 'value' + * is null, the setter will not be called. Exceptions that are raised from the setter will + * be logged. + * + * @param setter The setter to call. + * @param value The value to use with the setter. + */ + private void setValOrLog(ValueSetter setter, String value) { + // ignore null values as they indicate a setting that is not set yet + if (value == null || value.isEmpty()) + return; + try { - handler.operation(); + setter.set(value); } catch (CentralRepoException | NumberFormatException e) { LOGGER.log(Level.WARNING, "There was an error in converting central repo postgres settings", e); @@ -73,10 +85,10 @@ public class CentralRepoPostgresSettingsUtil { } /** - * This interface represents an action that potentially throws an exception. + * This interface represents a setter that potentially throws an exception. */ - private interface TryHandler { - void operation() throws CentralRepoException, NumberFormatException; + private interface ValueSetter { + void set(String value) throws CentralRepoException, NumberFormatException; } /** @@ -96,15 +108,12 @@ public class CentralRepoPostgresSettingsUtil { return settings; } - logException(() -> settings.setHost(muConn.getHost())); - logException(() -> settings.setDbName(PostgresConnectionSettings.DEFAULT_DBNAME)); - logException(() -> settings.setUserName(muConn.getUserName())); - - logException(() -> settings.setPort(Integer.parseInt(muConn.getPort()))); - logException(() -> settings.setBulkThreshold(RdbmsCentralRepo.DEFAULT_BULK_THRESHHOLD)); - - logException(() -> settings.setPassword(muConn.getPassword())); + setValOrLog((v) -> settings.setHost(v), muConn.getHost()); + setValOrLog((v) -> settings.setUserName(v), muConn.getUserName()); + setValOrLog((v) -> settings.setPassword(v), muConn.getPassword()); + setValOrLog((v) -> settings.setPort(Integer.parseInt(v)), muConn.getPort()); + return settings; } @@ -120,24 +129,27 @@ public class CentralRepoPostgresSettingsUtil { Map keyVals = ModuleSettings.getConfigSettings(MODULE_KEY); - logException(() -> settings.setHost(keyVals.get(HOST_KEY))); - logException(() -> settings.setDbName(keyVals.get(DBNAME_KEY))); - logException(() -> settings.setUserName(keyVals.get(USER_KEY))); + setValOrLog((v) -> settings.setHost(v), keyVals.get(HOST_KEY)); + setValOrLog((v) -> settings.setDbName(v), keyVals.get(DBNAME_KEY)); + setValOrLog((v) -> settings.setUserName(v), keyVals.get(USER_KEY)); - logException(() -> settings.setPort(Integer.parseInt(keyVals.get(PORT_KEY)))); - logException(() -> settings.setBulkThreshold(Integer.parseInt(keyVals.get((BULK_THRESHOLD_KEY))))); + setValOrLog((v) -> settings.setPort(Integer.parseInt(v)), keyVals.get(PORT_KEY)); + setValOrLog((v) -> settings.setBulkThreshold(Integer.parseInt(v)), keyVals.get((BULK_THRESHOLD_KEY))); String passwordHex = keyVals.get(PASSWORD_KEY); - String password; - try { - password = TextConverter.convertHexTextToText(passwordHex); - } catch (TextConverterException ex) { - LOGGER.log(Level.WARNING, "Failed to convert password from hex text to text.", ex); - password = null; + if (passwordHex != null) { + String password; + try { + password = TextConverter.convertHexTextToText(passwordHex); + } catch (TextConverterException ex) { + LOGGER.log(Level.WARNING, "Failed to convert password from hex text to text.", ex); + password = null; + } + + final String finalPassword = password; + setValOrLog((v) -> settings.setPassword(v), finalPassword); } - final String finalPassword = password; - logException(() -> settings.setPassword(finalPassword)); return settings; } From 60f6077fc7ff807f08987027820fb1dc81acb667 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Wed, 18 Mar 2020 22:20:53 -0400 Subject: [PATCH 21/41] Reverted form changes --- .../autopsy/contentviewers/MediaPlayerPanel.form | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form index 793e31830b..e5a4279d54 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form @@ -63,7 +63,7 @@ - + @@ -129,6 +129,12 @@ + + + + + + @@ -326,4 +332,4 @@ - + \ No newline at end of file From 0ff95aa2769e66e3e2f4cdbeb1f6ab8e3b850a25 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Wed, 18 Mar 2020 22:22:05 -0400 Subject: [PATCH 22/41] Added new line ending : --- .../org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form index e5a4279d54..0b00c43d8a 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form @@ -332,4 +332,4 @@ - \ No newline at end of file + From 2a439826dafa961f318ca7e24e57336bd50db321 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Wed, 18 Mar 2020 22:33:22 -0400 Subject: [PATCH 23/41] Updated bundle message and form file --- .../autopsy/contentviewers/Bundle.properties-MERGED | 2 +- .../autopsy/contentviewers/MediaPlayerPanel.form | 8 +------- .../autopsy/contentviewers/MediaPlayerPanel.java | 12 ++++++------ 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED index bf669b8cc4..c0a6f73aaf 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Bundle.properties-MERGED @@ -41,7 +41,7 @@ MediaFileViewer.AccessibleContext.accessibleDescription= MediaFileViewer.title=Media MediaFileViewer.toolTip=Displays supported multimedia files (images, videos, audio) MediaPlayerPanel.noSupport=File not supported. -MediaPlayerPanel.playbackDisabled=A problem was encountered with the video playback service. Video playback will be disabled for the remainder of the session. +MediaPlayerPanel.playbackDisabled=A problem was encountered with the video and audio playback service. Video and audio playback will be disabled for the remainder of the session. MediaPlayerPanel.timeFormat=%02d:%02d:%02d MediaPlayerPanel.unknownTime=Unknown MediaViewImagePanel.createTagOption=Create diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form index 0b00c43d8a..793e31830b 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.form @@ -63,7 +63,7 @@ - + @@ -129,12 +129,6 @@ - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java index 2d69819e1a..40122acea7 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/MediaPlayerPanel.java @@ -214,7 +214,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie //The slider is a shared resource between the VideoPanelUpdater //and the TrackListener on the slider itself. private final Semaphore sliderLock; - + private static volatile boolean IS_GST_ENABLED = true; /** @@ -424,10 +424,10 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie @Override public boolean isSupported(AbstractFile file) { - if(!IS_GST_ENABLED) { + if (!IS_GST_ENABLED) { return false; } - + String extension = file.getNameExtension(); /** * Although it seems too restrictive, requiring both a supported @@ -547,8 +547,8 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie */ @NbBundle.Messages({ "MediaPlayerPanel.playbackDisabled=A problem was encountered with" - + " the video playback service. Video playback will" - + " be disabled for the remainder of the session." + + " the video and audio playback service. Video and audio " + + "playback will be disabled for the remainder of the session." }) @Override protected void done() { @@ -562,7 +562,7 @@ public class MediaPlayerPanel extends JPanel implements MediaFileViewer.MediaVie GstStatus loadStatus = GstLoader.tryLoad(); if (loadStatus == GstStatus.FAILURE) { MessageNotifyUtil.Message.error(Bundle.MediaPlayerPanel_playbackDisabled()); - + // This will disable the panel for future use. IS_GST_ENABLED = false; return; From 9d58f0220cfbd919c01afa1f5f5bb0cd847a958e Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Wed, 18 Mar 2020 22:42:01 -0400 Subject: [PATCH 24/41] Codacy comments and adjusted bundle message --- .../sleuthkit/autopsy/contentviewers/utils/GstLoader.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java b/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java index b2ad257847..57da88e0a2 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java @@ -61,7 +61,14 @@ public class GstLoader { return status; } + /** + * The various init statuses that tryLoad can return. + */ public enum GstStatus { SUCCESS, FAILURE } + + private GstLoader() { + + } } From 45e9222bccda7c2add909fdd09255d2251ad1848 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 07:48:10 -0400 Subject: [PATCH 25/41] 6032 translated file names in results view --- .../datamodel/BlackboardArtifactNode.java | 234 ++++++++++-------- .../datamodel/BlackboardArtifactTagNode.java | 15 +- .../datamodel/Bundle.properties-MERGED | 3 + .../autopsy/datamodel/ContentTagNode.java | 48 ++-- .../datamodel/DisplayableItemNode.java | 25 +- .../sleuthkit/autopsy/datamodel/TagNode.java | 135 ++++++++++ .../directorytree/DataResultFilterNode.java | 23 +- 7 files changed, 317 insertions(+), 166 deletions(-) create mode 100755 Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 055d322203..6663c87bb3 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -127,7 +127,8 @@ public class BlackboardArtifactNode extends AbstractContentNode(Bundle.BlackboardArtifactNode_createSheet_score_name(), Bundle.BlackboardArtifactNode_createSheet_score_displayName(), scoData.getScoreAndDescription().getRight(), scoData.getScoreAndDescription().getLeft())); + updateSheet(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_score_name(), + Bundle.BlackboardArtifactNode_createSheet_score_displayName(), + scoData.getScoreAndDescription().getRight(), + scoData.getScoreAndDescription().getLeft())); } if (scoData.getComment() != null) { - updateSheet(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_comment_name(), Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), NO_DESCR, scoData.getComment())); + updateSheet(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_comment_name(), + Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), + NO_DESCR, scoData.getComment())); } if (scoData.getCountAndDescription() != null) { - updateSheet(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(), scoData.getCountAndDescription().getRight(), scoData.getCountAndDescription().getLeft())); + updateSheet(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_count_name(), + Bundle.BlackboardArtifactNode_createSheet_count_displayName(), + scoData.getCountAndDescription().getRight(), + scoData.getCountAndDescription().getLeft())); } } else if (eventType.equals(FileNameTransTask.getPropertyName())) { /* * Replace the value of the Source File property with the * translated name via setDisplayName (see note in createSheet), - * and put the untranslated name in the Original Name property. - * Also set the tooltip to the original name. + * and put the untranslated name in the Original Name property + * and in the tooltip. */ + translatedSourceName = evt.getNewValue().toString(); setDisplayName(evt.getNewValue().toString()); setShortDescription(evt.getOldValue().toString()); - updateSheet(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_srcFile_name(), Bundle.BlackboardArtifactNode_createSheet_srcFile_displayName(), NO_DESCR, (String) evt.getNewValue())); - //updateSheet(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_srcFile_origName(), Bundle.BlackboardArtifactNode_createSheet_srcFile_origDisplayName(), NO_DESCR, (String) evt.getOldValue())); + updateSheet(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_srcFile_origName(), + Bundle.BlackboardArtifactNode_createSheet_srcFile_origDisplayName(), + NO_DESCR, + evt.getOldValue().toString())); } } }; @@ -225,17 +241,15 @@ public class BlackboardArtifactNode extends AbstractContentNode( Bundle.BlackboardArtifactNode_createSheet_srcFile_name(), Bundle.BlackboardArtifactNode_createSheet_srcFile_displayName(), NO_DESCR, - this.getSourceName())); + getDisplayName())); if (TextTranslationService.getInstance().hasProvider() && UserPreferences.displayTranslatedFileNames()) { /* @@ -431,8 +459,8 @@ public class BlackboardArtifactNode extends AbstractContentNode(Bundle.BlackboardArtifactNode_createSheet_score_name(), Bundle.BlackboardArtifactNode_createSheet_score_displayName(), VALUE_LOADING, "")); - sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_comment_name(), Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), VALUE_LOADING, "")); + sheetSet.put(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_score_name(), + Bundle.BlackboardArtifactNode_createSheet_score_displayName(), + VALUE_LOADING, + "")); + sheetSet.put(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_comment_name(), + Bundle.BlackboardArtifactNode_createSheet_comment_displayName(), + VALUE_LOADING, + "")); if (CentralRepository.isEnabled()) { - sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_count_name(), Bundle.BlackboardArtifactNode_createSheet_count_displayName(), VALUE_LOADING, "")); + sheetSet.put(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_count_name(), + Bundle.BlackboardArtifactNode_createSheet_count_displayName(), + VALUE_LOADING, + "")); } backgroundTasksPool.submit(new GetSCOTask(new WeakReference<>(this), weakAppEventListener)); } @@ -463,20 +503,16 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.artifactType.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.artifactType.displayName"), - NO_DESCR, - associatedArtifact.getDisplayName())); - sheetSet - .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.artifactDetails.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.artifactDetails.displayName"), - NO_DESCR, - associatedArtifact.getShortDescription())); + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactType.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactType.displayName"), + NO_DESCR, + associatedArtifact.getDisplayName())); + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactDetails.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.artifactDetails.displayName"), + NO_DESCR, + associatedArtifact.getShortDescription())); } } catch (TskCoreException | NoCurrentCaseException ex) { logger.log(Level.SEVERE, MessageFormat.format("Error getting associated artifact of TSK_INTERESTING_ARTIFACT_HIT artifact (objID={0}))", artifact.getId()), ex); //NON-NLS @@ -523,20 +559,16 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.ext.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.ext.displayName"), + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.ext.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.ext.displayName"), NO_DESCR, ext)); - sheetSet - .put(new NodeProperty<>( - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.mimeType.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.mimeType.displayName"), - NO_DESCR, - actualMimeType)); + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.mimeType.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.mimeType.displayName"), + NO_DESCR, + actualMimeType)); } /* @@ -556,10 +588,8 @@ public class BlackboardArtifactNode extends AbstractContentNode( - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.filePath.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.filePath.displayName"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.filePath.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.filePath.displayName"), NO_DESCR, sourcePath)); } @@ -571,42 +601,33 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileModifiedTime.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileModifiedTime.displayName"), - "", - file == null ? "" : ContentUtils.getStringTime(file.getMtime(), file))); - sheetSet - .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileChangedTime.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileChangedTime.displayName"), - "", - file == null ? "" : ContentUtils.getStringTime(file.getCtime(), file))); - sheetSet - .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileAccessedTime.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileAccessedTime.displayName"), - "", - file == null ? "" : ContentUtils.getStringTime(file.getAtime(), file))); - sheetSet - .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileCreatedTime.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileCreatedTime.displayName"), - "", - file == null ? "" : ContentUtils.getStringTime(file.getCrtime(), file))); - sheetSet - .put(new NodeProperty<>(NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileSize.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "ContentTagNode.createSheet.fileSize.displayName"), - "", - file == null ? "" : file.getSize())); - sheetSet.put(new NodeProperty<>(Bundle.BlackboardArtifactNode_createSheet_artifactMD5_name(), + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.displayName"), + "", + file == null ? "" : ContentUtils.getStringTime(file.getMtime(), file))); + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileChangedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileChangedTime.displayName"), + "", + file == null ? "" : ContentUtils.getStringTime(file.getCtime(), file))); + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileAccessedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileAccessedTime.displayName"), + "", + file == null ? "" : ContentUtils.getStringTime(file.getAtime(), file))); + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileCreatedTime.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileCreatedTime.displayName"), + "", + file == null ? "" : ContentUtils.getStringTime(file.getCrtime(), file))); + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileSize.displayName"), + "", + file == null ? "" : file.getSize())); + sheetSet.put(new NodeProperty<>( + Bundle.BlackboardArtifactNode_createSheet_artifactMD5_name(), Bundle.BlackboardArtifactNode_createSheet_artifactMD5_displayName(), "", file == null ? "" : StringUtils.defaultString(file.getMd5Hash()))); @@ -629,10 +650,8 @@ public class BlackboardArtifactNode extends AbstractContentNode( - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.dataSrc.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.dataSrc.displayName"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.dataSrc.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.dataSrc.displayName"), NO_DESCR, dataSourceStr)); } @@ -655,18 +674,15 @@ public class BlackboardArtifactNode extends AbstractContentNode(NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.fileSize.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.fileSize.displayName"), + sheetSet.put(new NodeProperty<>( + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.fileSize.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.fileSize.displayName"), NO_DESCR, size)); sheetSet .put(new NodeProperty<>( - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.path.name"), - NbBundle.getMessage(BlackboardArtifactNode.class, - "BlackboardArtifactNode.createSheet.path.displayName"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.path.name"), + NbBundle.getMessage(BlackboardArtifactNode.class, "BlackboardArtifactNode.createSheet.path.displayName"), NO_DESCR, path)); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java index a6a0a66590..6068615592 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactTagNode.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2013-2018 Basis Technology Corp. + * Copyright 2013-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,13 +24,11 @@ import java.util.Arrays; import java.util.List; import java.util.logging.Level; import javax.swing.Action; -import org.openide.nodes.Children; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; import org.openide.util.lookup.Lookups; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil; import org.sleuthkit.autopsy.timeline.actions.ViewArtifactInTimelineAction; import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction; import org.sleuthkit.datamodel.AbstractFile; @@ -46,14 +44,14 @@ import static org.sleuthkit.autopsy.datamodel.Bundle.*; * tag name nodes have tag type child nodes; tag type nodes are the parents of * either content or blackboard artifact tag nodes. */ -public class BlackboardArtifactTagNode extends DisplayableItemNode { +public class BlackboardArtifactTagNode extends TagNode { private static final Logger LOGGER = Logger.getLogger(BlackboardArtifactTagNode.class.getName()); private static final String ICON_PATH = "org/sleuthkit/autopsy/images/green-tag-icon-16.png"; //NON-NLS private final BlackboardArtifactTag tag; public BlackboardArtifactTagNode(BlackboardArtifactTag tag) { - super(Children.LEAF, Lookups.fixed(tag, tag.getArtifact(), tag.getContent())); + super(Lookups.fixed(tag, tag.getArtifact(), tag.getContent()), tag.getContent()); super.setName(tag.getContent().getName()); super.setDisplayName(tag.getContent().getName()); this.setIconBaseWithExtension(ICON_PATH); @@ -75,6 +73,7 @@ public class BlackboardArtifactTagNode extends DisplayableItemNode { NbBundle.getMessage(this.getClass(), "BlackboardArtifactTagNode.createSheet.srcFile.text"), "", tag.getContent().getName())); + addOriginalNameProp(properties); String contentPath; try { contentPath = tag.getContent().getUniquePath(); @@ -82,7 +81,6 @@ public class BlackboardArtifactTagNode extends DisplayableItemNode { Logger.getLogger(ContentTagNode.class.getName()).log(Level.SEVERE, "Failed to get path for content (id = " + tag.getContent().getId() + ")", ex); //NON-NLS contentPath = NbBundle.getMessage(this.getClass(), "BlackboardArtifactTagNode.createSheet.unavail.text"); } - properties.put(new NodeProperty<>( NbBundle.getMessage(this.getClass(), "BlackboardArtifactTagNode.createSheet.srcFilePath.text"), NbBundle.getMessage(this.getClass(), "BlackboardArtifactTagNode.createSheet.srcFilePath.text"), @@ -146,11 +144,6 @@ public class BlackboardArtifactTagNode extends DisplayableItemNode { return visitor.visit(this); } - @Override - public boolean isLeafTypeNode() { - return true; - } - @Override public String getItemType() { return getClass().getName(); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED index 3a16272a96..0d5c75740d 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/datamodel/Bundle.properties-MERGED @@ -92,6 +92,7 @@ Category.two=CAT-2: Child Exploitation (Non-Illegal/Age Difficult) Category.zero=CAT-0: Uncategorized ContentTagNode.createSheet.artifactMD5.displayName=MD5 Hash ContentTagNode.createSheet.artifactMD5.name=MD5 Hash +ContentTagNode.createSheet.origFileName=Original Name ContentTagNode.createSheet.userName.text=User Name DeletedContent.allDelFilter.text=All DeletedContent.createSheet.filterType.desc=no description @@ -347,6 +348,8 @@ TagNameNode.bbArtTagTypeNodeKey.text=Result Tags TagNameNode.bookmark.text=Bookmark TagNameNode.createSheet.name.name=Name TagNameNode.createSheet.name.displayName=Name +TagNode.propertySheet.origName=Original Name +TagNode.propertySheet.origNameDisplayName=Original Name TagsNode.displayName.text=Tags TagsNode.createSheet.name.name=Name TagsNode.createSheet.name.displayName=Name diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java index e213e460cb..89d6c2fae2 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/ContentTagNode.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2013-2016 Basis Technology Corp. + * Copyright 2013-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,7 +24,6 @@ import java.util.List; import java.util.logging.Level; import javax.swing.Action; import org.apache.commons.lang3.StringUtils; -import org.openide.nodes.Children; import org.openide.nodes.Sheet; import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; @@ -39,18 +38,16 @@ import org.sleuthkit.datamodel.TskCoreException; /** * Instances of this class wrap ContentTag objects. In the Autopsy presentation * of the SleuthKit data model, they are leaf nodes of a tree consisting of - * content and blackboard artifact tags, grouped first by tag type, then by tag - * name. + * content and artifact tags, grouped first by tag type, then by tag name. */ -class ContentTagNode extends DisplayableItemNode { +class ContentTagNode extends TagNode { private static final Logger LOGGER = Logger.getLogger(ContentTagNode.class.getName()); - private static final String ICON_PATH = "org/sleuthkit/autopsy/images/blue-tag-icon-16.png"; //NON-NLS private final ContentTag tag; - public ContentTagNode(ContentTag tag) { - super(Children.LEAF, Lookups.fixed(tag, tag.getContent())); + ContentTagNode(ContentTag tag) { + super(Lookups.fixed(tag, tag.getContent()), tag.getContent()); super.setName(tag.getContent().getName()); super.setDisplayName(tag.getContent().getName()); this.setIconBaseWithExtension(ICON_PATH); @@ -58,6 +55,7 @@ class ContentTagNode extends DisplayableItemNode { } @Messages({ + "ContentTagNode.createSheet.origFileName=Original Name", "ContentTagNode.createSheet.artifactMD5.displayName=MD5 Hash", "ContentTagNode.createSheet.artifactMD5.name=MD5 Hash", "ContentTagNode.createSheet.userName.text=User Name"}) @@ -79,15 +77,19 @@ class ContentTagNode extends DisplayableItemNode { properties = Sheet.createPropertiesSet(); propertySheet.put(properties); } - properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.file.name"), + properties.put(new NodeProperty<>( + NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.file.name"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.file.displayName"), "", content.getName())); - properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.filePath.name"), + addOriginalNameProp(properties); + properties.put(new NodeProperty<>( + NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.filePath.name"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.filePath.displayName"), "", contentPath)); - properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.comment.name"), + properties.put(new NodeProperty<>( + NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.comment.name"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.comment.displayName"), "", tag.getComment())); @@ -95,23 +97,28 @@ class ContentTagNode extends DisplayableItemNode { NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileModifiedTime.displayName"), "", file != null ? ContentUtils.getStringTime(file.getMtime(), file) : "")); - properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileChangedTime.name"), + properties.put(new NodeProperty<>( + NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileChangedTime.name"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileChangedTime.displayName"), "", file != null ? ContentUtils.getStringTime(file.getCtime(), file) : "")); - properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileAccessedTime.name"), + properties.put(new NodeProperty<>( + NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileAccessedTime.name"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileAccessedTime.displayName"), "", file != null ? ContentUtils.getStringTime(file.getAtime(), file) : "")); - properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileCreatedTime.name"), + properties.put(new NodeProperty<>( + NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileCreatedTime.name"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileCreatedTime.displayName"), "", file != null ? ContentUtils.getStringTime(file.getCrtime(), file) : "")); - properties.put(new NodeProperty<>(NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileSize.name"), + properties.put(new NodeProperty<>( + NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileSize.name"), NbBundle.getMessage(this.getClass(), "ContentTagNode.createSheet.fileSize.displayName"), "", content.getSize())); - properties.put(new NodeProperty<>(Bundle.ContentTagNode_createSheet_artifactMD5_name(), + properties.put(new NodeProperty<>( + Bundle.ContentTagNode_createSheet_artifactMD5_name(), Bundle.ContentTagNode_createSheet_artifactMD5_displayName(), "", file != null ? StringUtils.defaultString(file.getMd5Hash()) : "")); @@ -128,8 +135,7 @@ class ContentTagNode extends DisplayableItemNode { List actions = new ArrayList<>(); actions.addAll(Arrays.asList(super.getActions(context))); - AbstractFile file = getLookup().lookup(AbstractFile.class - ); + AbstractFile file = getLookup().lookup(AbstractFile.class); if (file != null) { actions.add(ViewFileInTimelineAction.createViewFileAction(file)); } @@ -144,13 +150,9 @@ class ContentTagNode extends DisplayableItemNode { return visitor.visit(this); } - @Override - public boolean isLeafTypeNode() { - return true; - } - @Override public String getItemType() { return getClass().getName(); } + } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNode.java index c723d99b55..c6bc88129a 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNode.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2012-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.datamodel; import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; +import org.openide.nodes.Sheet; import org.openide.util.Lookup; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; @@ -142,4 +143,26 @@ public abstract class DisplayableItemNode extends AbstractNode { return selectedChildNodeInfo; } + /** + * Updates the node property sheet by replacing existing properties with new + * properties with the same property name. + * + * @param newProps The replacement property objects. + */ + protected synchronized final void updatePropertySheet(NodeProperty... newProps) { + Sheet currentSheet = this.getSheet(); + Sheet.Set currentPropsSet = currentSheet.get(Sheet.PROPERTIES); + Property[] currentProps = currentPropsSet.getProperties(); + for (NodeProperty newProp : newProps) { + for (int i = 0; i < currentProps.length; i++) { + if (currentProps[i].getName().equals(newProp.getName())) { + currentProps[i] = newProp; + } + } + } + currentPropsSet.put(currentProps); + currentSheet.put(currentPropsSet); + this.setSheet(currentSheet); + } + } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java new file mode 100755 index 0000000000..7d4d8d467c --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java @@ -0,0 +1,135 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020-2020 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.datamodel; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import org.openide.nodes.Children; +import org.openide.nodes.Sheet; +import org.openide.util.Lookup; +import org.openide.util.NbBundle; +import org.openide.util.WeakListeners; +import org.sleuthkit.autopsy.core.UserPreferences; +import org.sleuthkit.autopsy.datamodel.utils.FileNameTransTask; +import org.sleuthkit.autopsy.texttranslation.TextTranslationService; +import org.sleuthkit.datamodel.Content; + +/** + * An abstract superclass for a node that represents a tag, uses the name of a + * given Content object as its display name, and has a property sheet with an + * original name property when machine translation is enabled. + * + * The translation of the Content name is done in a background thread. The + * translated name is made the display name of the node and the untranslated + * name is put into both the original name property and into the node's tooltip. + * + * TODO (Jira-): Consider modifying this class to be able to use it more broadly + * within the Autopsy data model (i.e., AbstractNode suclasses). It's not really + * specific to a tag node. + */ +@NbBundle.Messages({ + "TagNode.propertySheet.origName=Original Name", + "TagNode.propertySheet.origNameDisplayName=Original Name" +}) +abstract class TagNode extends DisplayableItemNode { + + private final static String ORIG_NAME_PROP_NAME = Bundle.TagNode_propertySheet_origName(); + private final static String ORIG_NAME_PROP_DISPLAY_NAME = Bundle.TagNode_propertySheet_origNameDisplayName(); + + private final String originalName; + private volatile String translatedName; // Only computed once, in a background thread. + + /* + * The node has an event listener that is wrapped in a weak reference that + * allows the node to be garbage collected when the NetBeans infrastructure + * discards it. If this is not done, it has been shown that a strong + * reference to the listener prevents garbage collection of this node. + */ + private final PropertyChangeListener listener = WeakListeners.propertyChange(new NameTranslationListener(), null); + + /** + * An abstract superclass for a node that represents a tag, uses the name of + * a given Content object as its display name, and has a property sheet with + * an untranslated file name property when machine translation is enabled. + * + * @param lookup The Lookup of the node. + * @param content The Content to use for the node display name. + */ + TagNode(Lookup lookup, Content content) { + super(Children.LEAF, lookup); + originalName = content.getName(); + } + + @Override + public boolean isLeafTypeNode() { + return true; + } + + @Override + abstract public String getItemType(); + + @Override + abstract public T accept(DisplayableItemNodeVisitor visitor); + + /** + * Adds an original name property to the node's property sheet and submits + * an original name translation task. + * + * The translation of the original name is done in a background thread. The + * translated name is made the display name of the node and the untranslated + * name is put into both the original name property and into the node's + * tooltip. + * + * @param properties The node's property sheet. + */ + protected void addOriginalNameProp(Sheet.Set properties) { + if (TextTranslationService.getInstance().hasProvider() && UserPreferences.displayTranslatedFileNames()) { + properties.put(new NodeProperty<>( + ORIG_NAME_PROP_NAME, + ORIG_NAME_PROP_DISPLAY_NAME, + "", + translatedName != null ? translatedName : "")); + if (translatedName == null) { + new FileNameTransTask(originalName, this, listener).submit(); + } + } + } + + /* + * A listener for PropertyChangeEvents from a background task used to + * translate the original display name associated with the node. + */ + private class NameTranslationListener implements PropertyChangeListener { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + String eventType = evt.getPropertyName(); + if (eventType.equals(FileNameTransTask.getPropertyName())) { + setDisplayName(evt.getNewValue().toString()); + setShortDescription(evt.getOldValue().toString()); + updatePropertySheet(new NodeProperty<>( + ORIG_NAME_PROP_NAME, + ORIG_NAME_PROP_DISPLAY_NAME, + "", + evt.getOldValue().toString())); + } + } + } + +} diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java b/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java index 522d3836c3..a412bb5970 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2019 Basis Technology Corp. + * Copyright 2012-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -187,27 +187,6 @@ public class DataResultFilterNode extends FilterNode { return propertySets; } - /** - * Gets the display name for the wrapped node. - * - * OutlineView used in the DataResult table uses getDisplayName() to - * populate the first column, which is Source File. - * - * Hence this override to return the 'correct' displayName for the wrapped - * node. - * - * @return The display name for the node. - */ - @Override - public String getDisplayName() { - final Node orig = getOriginal(); - String name = orig.getDisplayName(); - if ((orig instanceof BlackboardArtifactNode)) { - name = ((BlackboardArtifactNode) orig).getSourceName(); - } - return name; - } - /** * Adds information about which child node of this node, if any, should be * selected. Can be null. From 060467f6199039097a605caa1b8d31c99efe0108 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 07:57:27 -0400 Subject: [PATCH 26/41] 6032 translated file names in results view --- Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java index 7d4d8d467c..e0b5d89905 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java @@ -39,7 +39,7 @@ import org.sleuthkit.datamodel.Content; * translated name is made the display name of the node and the untranslated * name is put into both the original name property and into the node's tooltip. * - * TODO (Jira-): Consider modifying this class to be able to use it more broadly + * TODO (Jira-6174): Consider modifying this class to be able to use it more broadly * within the Autopsy data model (i.e., AbstractNode suclasses). It's not really * specific to a tag node. */ From 89ccc44a56a36a776926655f4bd80cef40cea056 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 08:24:29 -0400 Subject: [PATCH 27/41] 6032 translated file names in results view --- .../sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index e2043846fe..99685d29a4 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -493,6 +493,8 @@ public abstract class AbstractAbstractFileNode extends A /** * Translates the name of the file this node represents. An empty string * will be returned if the translation fails for any reason. + * + * @return The translated file name or the empty string. */ String getTranslatedFileName() { try { From cdea715cf702fe3f95f5e99b3f2d0fd9bc9559fc Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 08:30:02 -0400 Subject: [PATCH 28/41] 6032 translated file names in results view --- .../autopsy/datamodel/BlackboardArtifactNode.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 6663c87bb3..a716d5eb64 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -209,14 +209,15 @@ public class BlackboardArtifactNode extends AbstractContentNode( Bundle.BlackboardArtifactNode_createSheet_srcFile_origName(), Bundle.BlackboardArtifactNode_createSheet_srcFile_origDisplayName(), NO_DESCR, - evt.getOldValue().toString())); + originalName)); } } }; From a287d4704ac7d2a9ddf139b8cf97f101e1f29915 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 08:31:36 -0400 Subject: [PATCH 29/41] 6032 translated file names in results view --- .../autopsy/datamodel/BlackboardArtifactNode.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index a716d5eb64..cbf37d77ae 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -229,7 +229,7 @@ public class BlackboardArtifactNode extends AbstractContentNode(this), weakAppEventListener)); + backgroundTasksPool.submit(new GetSCOTask(new WeakReference<>(this), weakListener)); } /* From 915facbcb3fce881750d8feb8a283830e1b35600 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 08:36:46 -0400 Subject: [PATCH 30/41] 6032 translated file names in results view --- .../sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index cbf37d77ae..87eb7b6610 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -462,6 +462,9 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Thu, 19 Mar 2020 08:43:03 -0400 Subject: [PATCH 31/41] 6032 translated file names in results view --- .../sleuthkit/autopsy/datamodel/TagNode.java | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java index e0b5d89905..20bf7d9c95 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java @@ -55,14 +55,6 @@ abstract class TagNode extends DisplayableItemNode { private final String originalName; private volatile String translatedName; // Only computed once, in a background thread. - /* - * The node has an event listener that is wrapped in a weak reference that - * allows the node to be garbage collected when the NetBeans infrastructure - * discards it. If this is not done, it has been shown that a strong - * reference to the listener prevents garbage collection of this node. - */ - private final PropertyChangeListener listener = WeakListeners.propertyChange(new NameTranslationListener(), null); - /** * An abstract superclass for a node that represents a tag, uses the name of * a given Content object as its display name, and has a property sheet with @@ -106,7 +98,7 @@ abstract class TagNode extends DisplayableItemNode { "", translatedName != null ? translatedName : "")); if (translatedName == null) { - new FileNameTransTask(originalName, this, listener).submit(); + new FileNameTransTask(originalName, this, new NameTranslationListener()).submit(); } } } @@ -121,13 +113,15 @@ abstract class TagNode extends DisplayableItemNode { public void propertyChange(PropertyChangeEvent evt) { String eventType = evt.getPropertyName(); if (eventType.equals(FileNameTransTask.getPropertyName())) { - setDisplayName(evt.getNewValue().toString()); - setShortDescription(evt.getOldValue().toString()); + translatedName = evt.getNewValue().toString(); + String originalName = evt.getOldValue().toString(); + setDisplayName(translatedName); + setShortDescription(originalName); updatePropertySheet(new NodeProperty<>( ORIG_NAME_PROP_NAME, ORIG_NAME_PROP_DISPLAY_NAME, "", - evt.getOldValue().toString())); + originalName)); } } } From 9c14a4de791b96725f0c4e0bd391732f984142e1 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 09:05:40 -0400 Subject: [PATCH 32/41] 6032 translated file names in results view --- .../datamodel/BlackboardArtifactNode.java | 108 ++++++------------ .../datamodel/Bundle.properties-MERGED | 2 - 2 files changed, 37 insertions(+), 73 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 87eb7b6610..2c6bc93446 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -152,25 +152,19 @@ public class BlackboardArtifactNode extends AbstractContentNode( NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.name"), NbBundle.getMessage(BlackboardArtifactNode.class, "ContentTagNode.createSheet.fileModifiedTime.displayName"), @@ -638,18 +608,16 @@ public class BlackboardArtifactNode extends AbstractContentNode tags = new ArrayList<>(); try { tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getBlackboardArtifactTagsByArtifact(artifact)); - if (srcContent != null) { - tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(srcContent)); - } + tags.addAll(Case.getCurrentCaseThrows().getServices().getTagsManager().getContentTagsByContent(srcContent)); } catch (TskCoreException | NoCurrentCaseException ex) { logger.log(Level.SEVERE, MessageFormat.format("Error getting tags for artifact and its source content (artifact objID={0})", artifact.getId()), ex); } @@ -725,7 +691,7 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Thu, 19 Mar 2020 09:06:39 -0400 Subject: [PATCH 33/41] 6032 translated file names in results view --- .../sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 2c6bc93446..48d95b506d 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -127,8 +127,8 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Thu, 19 Mar 2020 09:13:20 -0400 Subject: [PATCH 34/41] 6032 translated file names in results view --- .../autopsy/texttranslation/utils/FileNameTranslator.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/utils/FileNameTranslator.java b/Core/src/org/sleuthkit/autopsy/texttranslation/utils/FileNameTranslator.java index 71b8a859b4..cfd04dcb93 100755 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/utils/FileNameTranslator.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/utils/FileNameTranslator.java @@ -44,6 +44,9 @@ public class FileNameTranslator { /* * Don't attempt translation if the characters of the file name are all * ASCII chars. + * + * TODO (Jira-6175): This filter prevents translation of many + * non-English file names composed entirely of Latin chars. */ if (fileName.matches("^\\p{ASCII}+$")) { return ""; From 06eba0fe63a2176a8abdbfe4ad7db606513be877 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 19 Mar 2020 10:45:19 -0400 Subject: [PATCH 35/41] checks whether or not cr buttons need to be enabled each event change --- .../centralrepository/optionspanel/GlobalSettingsPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java index 78b2e9ca87..e84d2b90f7 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/optionspanel/GlobalSettingsPanel.java @@ -731,9 +731,9 @@ public final class GlobalSettingsPanel extends IngestModuleGlobalSettingsPanel i enableButtonSubComponents(cbUseCentralRepo.isSelected()); } else { load(); - enableDatabaseConfigureButton(cbUseCentralRepo.isSelected() && !caseIsOpen); } + enableDatabaseConfigureButton(cbUseCentralRepo.isSelected() && !caseIsOpen); } /** From df3f1ec2e81eaa68ddff0239765efd981d4c9e67 Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Thu, 19 Mar 2020 12:10:58 -0400 Subject: [PATCH 36/41] 6032 translated file names in results view --- .../autopsy/datamodel/AbstractAbstractFileNode.java | 4 ++-- Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java | 5 ++--- .../sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java | 4 ++-- ...{FileNameTranslator.java => FileNameTranslationUtil.java} | 4 ++-- 4 files changed, 8 insertions(+), 9 deletions(-) rename Core/src/org/sleuthkit/autopsy/texttranslation/utils/{FileNameTranslator.java => FileNameTranslationUtil.java} (96%) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index 99685d29a4..74ac603e0b 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -66,7 +66,7 @@ import org.sleuthkit.datamodel.Tag; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskData; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; -import org.sleuthkit.autopsy.texttranslation.utils.FileNameTranslator; +import org.sleuthkit.autopsy.texttranslation.utils.FileNameTranslationUtil; /** * An abstract node that encapsulates AbstractFile data @@ -498,7 +498,7 @@ public abstract class AbstractAbstractFileNode extends A */ String getTranslatedFileName() { try { - return FileNameTranslator.translate(content.getName()); + return FileNameTranslationUtil.translate(content.getName()); } catch (NoServiceProviderException | TranslationException ex) { logger.log(Level.WARNING, MessageFormat.format("Error translating file name (objID={0}))", content.getId()), ex); return ""; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java index 20bf7d9c95..9e0f1c7268 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java @@ -24,7 +24,6 @@ import org.openide.nodes.Children; import org.openide.nodes.Sheet; import org.openide.util.Lookup; import org.openide.util.NbBundle; -import org.openide.util.WeakListeners; import org.sleuthkit.autopsy.core.UserPreferences; import org.sleuthkit.autopsy.datamodel.utils.FileNameTransTask; import org.sleuthkit.autopsy.texttranslation.TextTranslationService; @@ -53,7 +52,7 @@ abstract class TagNode extends DisplayableItemNode { private final static String ORIG_NAME_PROP_DISPLAY_NAME = Bundle.TagNode_propertySheet_origNameDisplayName(); private final String originalName; - private volatile String translatedName; // Only computed once, in a background thread. + private volatile String translatedName; /** * An abstract superclass for a node that represents a tag, uses the name of @@ -103,7 +102,7 @@ abstract class TagNode extends DisplayableItemNode { } } - /* + /** * A listener for PropertyChangeEvents from a background task used to * translate the original display name associated with the node. */ diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java b/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java index 88ccac2d2f..8b755ec3dc 100755 --- a/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/utils/FileNameTransTask.java @@ -21,7 +21,7 @@ package org.sleuthkit.autopsy.datamodel.utils; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import org.openide.nodes.AbstractNode; -import org.sleuthkit.autopsy.texttranslation.utils.FileNameTranslator; +import org.sleuthkit.autopsy.texttranslation.utils.FileNameTranslationUtil; /** * An AbstractNodePropertySheetTask that translates a file name for an @@ -54,7 +54,7 @@ public class FileNameTransTask extends AbstractNodePropertySheetTask Date: Thu, 19 Mar 2020 16:15:23 -0400 Subject: [PATCH 37/41] Codacy suggestions round 2 --- .../org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java b/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java index 57da88e0a2..b6804d488a 100755 --- a/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java +++ b/Core/src/org/sleuthkit/autopsy/contentviewers/utils/GstLoader.java @@ -26,7 +26,7 @@ import org.sleuthkit.autopsy.coreutils.Logger; /** * A utility class that loads the gstreamer bindings. */ -public class GstLoader { +public final class GstLoader { private static final Logger logger = Logger.getLogger(GstLoader.class.getName()); private static GstStatus status; From 62be8d53605142d0864968627ab1d80860d5f389 Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 20 Mar 2020 08:05:53 -0400 Subject: [PATCH 38/41] 6133 add new default video thumb image --- .../autopsy/filequery/FileSearch.java | 49 +++++++++++------- .../images/failedToCreateVideoThumb.png | Bin 0 -> 2481 bytes 2 files changed, 29 insertions(+), 20 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/images/failedToCreateVideoThumb.png diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java index daa4124e8d..ae0e939498 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java @@ -95,6 +95,7 @@ class FileSearch { .build(); private static final int PREVIEW_SIZE = 256; private static volatile TextSummarizer summarizerToUse = null; + private static final BufferedImage VIDEO_DEFAULT_IMAGE = getDefaultVideoThumbnail(); /** * Run the file search and returns the SearchResults object for debugging. @@ -456,6 +457,15 @@ class FileSearch { + "AND blackboard_artifacts.obj_id IN (" + objIdList + ") "; // NON-NLS } + private static BufferedImage getDefaultVideoThumbnail() { + try { + return ImageIO.read(ImageUtils.class.getResourceAsStream("/org/sleuthkit/autopsy/images/failedToCreateVideoThumb.png"));//NON-NLS + } catch (IOException ex) { + logger.log(Level.SEVERE, "Failed to load 'failed to create video' placeholder.", ex); //NON-NLS + } + return null; + } + /** * Get the video thumbnails for a file which exists in a * VideoThumbnailsWrapper and update the VideoThumbnailsWrapper to include @@ -476,7 +486,6 @@ class FileSearch { cacheDirectory = null; logger.log(Level.WARNING, "Unable to get cache directory, video thumbnails will not be saved", ex); } - if (cacheDirectory == null || file.getMd5Hash() == null || !Paths.get(cacheDirectory, VIDEO_THUMBNAIL_DIR, file.getMd5Hash()).toFile().exists()) { java.io.File tempFile; try { @@ -488,7 +497,7 @@ class FileSearch { 0, 0, 0}; - thumbnailWrapper.setThumbnails(createDefaultThumbnailList(), framePositions); + thumbnailWrapper.setThumbnails(createDefaultThumbnailList(VIDEO_DEFAULT_IMAGE), framePositions); return; } if (tempFile.exists() == false || tempFile.length() < file.getSize()) { @@ -502,7 +511,7 @@ class FileSearch { 0, 0, 0}; - thumbnailWrapper.setThumbnails(createDefaultThumbnailList(), framePositions); + thumbnailWrapper.setThumbnails(createDefaultThumbnailList(VIDEO_DEFAULT_IMAGE), framePositions); return; } ContentUtils.writeToFile(file, tempFile, progress, null, true); @@ -523,7 +532,7 @@ class FileSearch { 0, 0, 0}; - thumbnailWrapper.setThumbnails(createDefaultThumbnailList(), framePositions); + thumbnailWrapper.setThumbnails(createDefaultThumbnailList(VIDEO_DEFAULT_IMAGE), framePositions); return; } double fps = videoFile.get(5); // gets frame per second @@ -535,7 +544,7 @@ class FileSearch { 0, 0, 0}; - thumbnailWrapper.setThumbnails(createDefaultThumbnailList(), framePositions); + thumbnailWrapper.setThumbnails(createDefaultThumbnailList(VIDEO_DEFAULT_IMAGE), framePositions); return; } if (Thread.interrupted()) { @@ -544,7 +553,7 @@ class FileSearch { 0, 0, 0}; - thumbnailWrapper.setThumbnails(createDefaultThumbnailList(), framePositions); + thumbnailWrapper.setThumbnails(createDefaultThumbnailList(VIDEO_DEFAULT_IMAGE), framePositions); return; } @@ -573,10 +582,10 @@ class FileSearch { logger.log(Level.WARNING, "Error seeking to " + framePositions[i] + "ms in {0}", file.getParentPath() + "/" + file.getName()); //NON-NLS // If we can't set the time, continue to the next frame position and try again. - videoThumbnails.add(ImageUtils.getDefaultThumbnail()); + videoThumbnails.add(VIDEO_DEFAULT_IMAGE); if (cacheDirectory != null) { try { - ImageIO.write((RenderedImage) ImageUtils.getDefaultThumbnail(), THUMBNAIL_FORMAT, + ImageIO.write(VIDEO_DEFAULT_IMAGE, THUMBNAIL_FORMAT, Paths.get(cacheDirectory, VIDEO_THUMBNAIL_DIR, file.getMd5Hash(), i + "-" + framePositions[i] + "." + THUMBNAIL_FORMAT).toFile()); //NON-NLS) } catch (IOException ex) { logger.log(Level.WARNING, "Unable to save default video thumbnail for " + file.getMd5Hash() + " at frame position " + framePositions[i], ex); @@ -588,10 +597,10 @@ class FileSearch { if (!videoFile.read(imageMatrix)) { logger.log(Level.WARNING, "Error reading frame at " + framePositions[i] + "ms from {0}", file.getParentPath() + "/" + file.getName()); //NON-NLS // If the image is bad for some reason, continue to the next frame position and try again. - videoThumbnails.add(ImageUtils.getDefaultThumbnail()); + videoThumbnails.add(VIDEO_DEFAULT_IMAGE); if (cacheDirectory != null) { try { - ImageIO.write((RenderedImage) ImageUtils.getDefaultThumbnail(), THUMBNAIL_FORMAT, + ImageIO.write(VIDEO_DEFAULT_IMAGE, THUMBNAIL_FORMAT, Paths.get(cacheDirectory, VIDEO_THUMBNAIL_DIR, file.getMd5Hash(), i + "-" + framePositions[i] + "." + THUMBNAIL_FORMAT).toFile()); //NON-NLS) } catch (IOException ex) { logger.log(Level.WARNING, "Unable to save default video thumbnail for " + file.getMd5Hash() + " at frame position " + framePositions[i], ex); @@ -602,10 +611,10 @@ class FileSearch { } // If the image is empty, return since no buffered image can be created. if (imageMatrix.empty()) { - videoThumbnails.add(ImageUtils.getDefaultThumbnail()); + videoThumbnails.add(VIDEO_DEFAULT_IMAGE); if (cacheDirectory != null) { try { - ImageIO.write((RenderedImage) ImageUtils.getDefaultThumbnail(), THUMBNAIL_FORMAT, + ImageIO.write(VIDEO_DEFAULT_IMAGE, THUMBNAIL_FORMAT, Paths.get(cacheDirectory, VIDEO_THUMBNAIL_DIR, file.getMd5Hash(), i + "-" + framePositions[i] + "." + THUMBNAIL_FORMAT).toFile()); //NON-NLS) } catch (IOException ex) { logger.log(Level.WARNING, "Unable to save default video thumbnail for " + file.getMd5Hash() + " at frame position " + framePositions[i], ex); @@ -660,7 +669,7 @@ class FileSearch { videoFile.release(); // close the file} } } else { - loadSavedThumbnails(cacheDirectory, thumbnailWrapper); + loadSavedThumbnails(cacheDirectory, thumbnailWrapper, VIDEO_DEFAULT_IMAGE); } } @@ -674,7 +683,7 @@ class FileSearch { * information about the file and the thumbnails * associated with it. */ - private static void loadSavedThumbnails(String cacheDirectory, VideoThumbnailsWrapper thumbnailWrapper) { + private static void loadSavedThumbnails(String cacheDirectory, VideoThumbnailsWrapper thumbnailWrapper, BufferedImage failedVideoThumbImage) { int[] framePositions = new int[4]; List videoThumbnails = new ArrayList<>(); int thumbnailNumber = 0; @@ -683,7 +692,7 @@ class FileSearch { try { videoThumbnails.add(ImageIO.read(Paths.get(cacheDirectory, VIDEO_THUMBNAIL_DIR, md5, fileName).toFile())); } catch (IOException ex) { - videoThumbnails.add(ImageUtils.getDefaultThumbnail()); + videoThumbnails.add(failedVideoThumbImage); logger.log(Level.WARNING, "Unable to read saved video thumbnail " + fileName + " for " + md5, ex); } int framePos = Integer.valueOf(FilenameUtils.getBaseName(fileName).substring(2)); @@ -699,12 +708,12 @@ class FileSearch { * * @return List containing the default thumbnail. */ - private static List createDefaultThumbnailList() { + private static List createDefaultThumbnailList(BufferedImage failedVideoThumbImage) { List videoThumbnails = new ArrayList<>(); - videoThumbnails.add(ImageUtils.getDefaultThumbnail()); - videoThumbnails.add(ImageUtils.getDefaultThumbnail()); - videoThumbnails.add(ImageUtils.getDefaultThumbnail()); - videoThumbnails.add(ImageUtils.getDefaultThumbnail()); + videoThumbnails.add(failedVideoThumbImage); + videoThumbnails.add(failedVideoThumbImage); + videoThumbnails.add(failedVideoThumbImage); + videoThumbnails.add(failedVideoThumbImage); return videoThumbnails; } diff --git a/Core/src/org/sleuthkit/autopsy/images/failedToCreateVideoThumb.png b/Core/src/org/sleuthkit/autopsy/images/failedToCreateVideoThumb.png new file mode 100644 index 0000000000000000000000000000000000000000..876402c150904d298d8362f4f6b870cdf3735553 GIT binary patch literal 2481 zcmb7GX*?5-AD%gK%(X(p$Ppq(IYwBy8FMUilrp)O$kE)SlWa?eAxcrkL>fvzM~<9x zg>vSKY3}QX&G6Uz|BL_s#q&I$=Xv*i^L?HaM|&$leo1}+03c{%ZH_wB*N5=o1s*bS z;Qi2{aD=0*OaZ0c(u_mHxq zsH;oa#tu?8$6GV{<2hTIfHpTdgh^mfiiXQgMevJb;;6U0kd*1^X?q>ls;X&uNir{g zTS^2tuj+xsDW%YqdPh`_))4W0ebRZ(?M_;EcWET<=a$ShKec}w^Q!H|ljzVN_sP^3KLDiwgS;-TLF_XE`1oe-+X#)TxoBiwq@hoK{;$>e`9o51afxe26^b4|yMS8AE# zf%ZP6eueM9c0kAvIy;vWW0ry+D|=ghBW3H~ttQ;{@QbXaO|&E*G_02a9R?4sR72y? z{p<~llD|WvzfA5j@)>#Ba+8!Vte5kLONo{`QxZPgZ#HFnXD|3etvo+ncpS!J|3h%z zm`hJ`FqS4wAkn3AA1k?-!a~F7+ZCocup1Vh!jsrYvu=m&lfBTkdezgp>%O;=>(Vle z5J{v_3-&xnQ9dap)V73fkSL%NN#uvLBg6=IQ#zMPDpBLAnm@w&0vbsO3Nz+>j1)YdLKg?=jDJ0$SIXV>vfb=p?ZCery9TD~iuvQ9CA1kZ<@|M)Yy zD;j66bn7`eaO=%k{U!_Srit%H7uJ)wBTpF8#a zESmG*_dK$gCqa+CWb=7&C1Q7JdA50+P);di;6f%ftEA;`Kh%pj@jb99??v3doy#(E zYiwWYY4K5!G8Y8*wha8B(5Lc~25Zs~`XtEhiSjA(FQ#e^FlvNua>-gOPt(Y_Q|11L zi%4^L<|0(4F1urZ-?n-dL0iKmIqrev>^vVp->I}HgOg&(9~d}=%Q+fo@rBXUm*tf) z$tPn}U*7xrZYk-vZq4#yue2zu4s;&jgm*XwjQk3&ZXiCJZ=_>m;JNn5tx*YfKLAy9 zWYv|y>*aO&HhFU=dq1OgYWezsOQv^1&T)@i4wsqS(gBS{zbWVZ@jC48*+!MX1(1ok ztquTZ?cZ?8;GS>+v6qU&g-hYwixb_H$Y}U;9kX&&`QwtkCc>VhE^QrD(RU+x+N8O&SyTy}ta7#{lzJXYebXn2KFu0~{Dm>h=-j2QF zucGnvzJ)!fmi8aF>ddSKokc+k%#7+>@d;Pzr5Z$Mp47B|!e9*phbvj1=SfUlPj#RBd?#|t*Tafu?1Be@>;O1t^Apg z=*gXc`iUdieEaYnD~|v2D_TVL^+g^gKy=;^LZGq+-Om1~w-v6|AOiILQG+l~%N5s7 zf30YML=W$9^)>0F75(EsGj=T7uql2~-;YQUEiva|{bjj$A$=a#oT88jvL5ic53kf1 z1+UE=L#~kvI9YF&S_hcE*lMkH+wW*4bIZ0PS1olerpC0errOJDu%pEhm=_TL9?DIq zPifUwY^!LR01GXs(^lFG;dNq`+WNrf=LX)~xxDv9zuT7>W!8(Jm;1YMe(?y!b8!j@ zdA+u{QQ^5fa_Pf6cGt^ar?%q)T(B3#WUefn@!NF!E!WG(X8VF!Wpj)7Mq>?0y4rgl zk6`%~gY7GZLReM`MV-+sA zgSs3WN>u&m`_t))h>3QU++YJYQ2(*jdyAOyskLLf#WJ%h0RzfNDoC7-M#G9ezKv&>~(Sl zf3scKBXZEp2+BtOi{082wLZ+Ehx-#I}`k?fJV7rg-hYfFehcB=s$^s=lcz7VXKclQoc{@qa zRW-`LklvQRw^{K9LuKg_E!XDyDj9+|R@*+dn1L-Zspk$-z5iLb_`b)e+Zj4RApoFl zuZ4pv`KljY6AGKlTpE3|KlrMu-6=q9oxLhKj^P;Vjnf%$s`xF6z??IgG7_nPlVQWe z$RbOaW2I@c>Ked=r>FP*qWv1ur35giLT&f4y#s3+01KW~*HCTpUWyimi8J$>;GPt( z(Se1q2ZIN1O}E>B0|XWgq^~wfp2oBut$M=@u$~b4v*OC!g$Pb@(fe(WGD}iJ1V!Zx zgKic(?;QS{XwN2h4g9z+QL}C& zG->v}q%Kk6@0#caSrUGyBCcQ>cgNLB<}S|Ez4<{?)0#AlcVfg^L=ob+{B~TD#vFhJ vxhM=kx9%Xo_2-Es?!wJ@1w59E#u9E#j7^5egb5waEP#!Ly?LoA=FWcr<*cWz literal 0 HcmV?d00001 From ed367ac36a6423ee63d5e13cf09376414e8516ae Mon Sep 17 00:00:00 2001 From: William Schaefer Date: Fri, 20 Mar 2020 08:08:58 -0400 Subject: [PATCH 39/41] 6133 clean up changes for video thumbnail --- Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java index ae0e939498..6a5543c9c9 100644 --- a/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java +++ b/Core/src/org/sleuthkit/autopsy/filequery/FileSearch.java @@ -23,7 +23,6 @@ import com.google.common.cache.CacheBuilder; import com.google.common.io.Files; import java.awt.Image; import java.awt.image.BufferedImage; -import java.awt.image.RenderedImage; import java.io.IOException; import java.io.Reader; import java.nio.file.Paths; @@ -457,6 +456,11 @@ class FileSearch { + "AND blackboard_artifacts.obj_id IN (" + objIdList + ") "; // NON-NLS } + /** + * Get the default image to display when a thumbnail is not available. + * + * @return The default video thumbnail. + */ private static BufferedImage getDefaultVideoThumbnail() { try { return ImageIO.read(ImageUtils.class.getResourceAsStream("/org/sleuthkit/autopsy/images/failedToCreateVideoThumb.png"));//NON-NLS From 39dc88814071414652f3ab7cec1915779ecc8e8b Mon Sep 17 00:00:00 2001 From: Richard Cordovano Date: Fri, 20 Mar 2020 10:14:47 -0400 Subject: [PATCH 40/41] 6032 fixes for review issues --- .../org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java | 2 +- Core/src/org/sleuthkit/autopsy/datamodel/TagNode.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 48d95b506d..8358dd7d34 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -432,7 +432,7 @@ public class BlackboardArtifactNode extends AbstractContentNode Date: Mon, 23 Mar 2020 10:31:42 -0400 Subject: [PATCH 41/41] Doxygen warnings --- .../centralrepository/datamodel/RdbmsCentralRepoFactory.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java index f76c13cd63..c01d3ee4e4 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/RdbmsCentralRepoFactory.java @@ -526,6 +526,7 @@ public class RdbmsCentralRepoFactory { * on the selected CR platform/RDMBS. * * @param pkName name of primary key. + * @param selectedPlatform The selected platform. * * @return SQL clause to be used in a Create table statement */ @@ -802,6 +803,7 @@ public class RdbmsCentralRepoFactory { * Inserts the default content in persona related tables. * * @param conn Database connection to use. + * @param selectedPlatform The selected platform. * * @return True if success, false otherwise. */