diff --git a/Core/nbproject/project.xml b/Core/nbproject/project.xml
index d142e0b8c9..de39ea6f9a 100644
--- a/Core/nbproject/project.xml
+++ b/Core/nbproject/project.xml
@@ -339,6 +339,7 @@
org.sleuthkit.autopsy.progress
org.sleuthkit.autopsy.report
org.sleuthkit.autopsy.tabulardatareader
+ org.sleuthkit.autopsy.texttranslation
org.sleuthkit.datamodel
diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java
index dcb2af3eef..b5624f8fa2 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java
@@ -1475,7 +1475,7 @@ public class Case {
public void notifyAddingDataSource(UUID eventId) {
eventPublisher.publish(new AddingDataSourceEvent(eventId));
}
-
+
/**
* Notifies case event subscribers that a data source failed to be added to
* the case.
diff --git a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java
index cb5f797c2b..3dc230cf21 100644
--- a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java
+++ b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java
@@ -72,7 +72,8 @@ public final class UserPreferences {
public static final String GROUP_ITEMS_IN_TREE_BY_DATASOURCE = "GroupItemsInTreeByDataSource"; //NON-NLS
public static final String SHOW_ONLY_CURRENT_USER_TAGS = "ShowOnlyCurrentUserTags";
public static final String HIDE_CENTRAL_REPO_COMMENTS_AND_OCCURRENCES = "HideCentralRepoCommentsAndOccurrences";
-
+ public static final String DISPLAY_TRANSLATED_NAMES = "DisplayTranslatedNames";
+
// Prevent instantiation.
private UserPreferences() {
}
@@ -244,6 +245,14 @@ public final class UserPreferences {
public static void setHideCentralRepoCommentsAndOccurrences(boolean value) {
preferences.putBoolean(HIDE_CENTRAL_REPO_COMMENTS_AND_OCCURRENCES, value);
}
+
+ public static void setDisplayTranslationFileNames(boolean value) {
+ preferences.putBoolean(DISPLAY_TRANSLATED_NAMES, value);
+ }
+
+ public static boolean displayTranslationFileNames() {
+ return preferences.getBoolean(DISPLAY_TRANSLATED_NAMES, false);
+ }
/**
* Reads persisted case database connection info.
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties
index 12ba493380..efd861fb24 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties
@@ -192,3 +192,5 @@ ViewPreferencesPanel.centralRepoLabel.text=Do not use Central Repository for:
ViewPreferencesPanel.commentsOccurencesColumnsCheckbox.text=C(omments) and O(ccurences) columns to reduce loading times
ViewPreferencesPanel.deletedFilesLimitCheckbox.text=Limit to 10,000
ViewPreferencesPanel.deletedFilesLimitLabel.text=Limit number of deleted files displayed:
+ViewPreferencesPanel.fileDisplayLabel.text=When displaying files:
+ViewPreferencesPanel.translatedNamesButton.text=Show translated file names
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form
index ddeb57bd74..096c24af11 100755
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form
@@ -92,6 +92,8 @@
+
+
@@ -114,9 +116,11 @@
+
+
@@ -125,14 +129,12 @@
+
-
-
-
@@ -174,9 +176,15 @@
-
+
+
+
+
-
+
+
+
+
@@ -356,6 +364,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java
index 51d4120449..2d7cb019c8 100755
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java
@@ -27,6 +27,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil;
import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.deletedFiles.DeletedFilePreferences;
import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent;
+import org.sleuthkit.autopsy.texttranslation.TextTranslationService;
/**
* Panel for configuring view preferences.
@@ -44,6 +45,12 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
public ViewPreferencesPanel(boolean immediateUpdates) {
initComponents();
this.immediateUpdates = immediateUpdates;
+
+ TextTranslationService translationService = new TextTranslationService();
+ if(!translationService.hasProvider()) {
+ translatedNamesButton.setVisible(false);
+ fileDisplayLabel.setVisible(false);
+ }
}
@Override
@@ -67,6 +74,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
commentsOccurencesColumnsCheckbox.setSelected(UserPreferences.hideCentralRepoCommentsAndOccurrences());
deletedFilesLimitCheckbox.setSelected(DeletedFilePreferences.getDefault().getShouldLimitDeletedFiles());
+ translatedNamesButton.setSelected(UserPreferences.displayTranslationFileNames());
// Current Case Settings
boolean caseIsOpen = Case.isCaseOpen();
@@ -90,6 +98,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
UserPreferences.setHideSlackFilesInViewsTree(viewsHideSlackCheckbox.isSelected());
UserPreferences.setShowOnlyCurrentUserTags(hideOtherUsersTagsCheckbox.isSelected());
UserPreferences.setHideCentralRepoCommentsAndOccurrences(commentsOccurencesColumnsCheckbox.isSelected());
+ UserPreferences.setDisplayTranslationFileNames(translatedNamesButton.isSelected());
storeGroupItemsInTreeByDataSource();
@@ -142,6 +151,8 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
centralRepoLabel = new javax.swing.JLabel();
deletedFilesLimitCheckbox = new javax.swing.JCheckBox();
deletedFilesLimitLabel = new javax.swing.JLabel();
+ translatedNamesButton = new javax.swing.JRadioButton();
+ fileDisplayLabel = new javax.swing.JLabel();
currentCaseSettingsPanel = new javax.swing.JPanel();
groupByDataSourceCheckbox = new javax.swing.JCheckBox();
currentSessionSettingsPanel = new javax.swing.JPanel();
@@ -244,6 +255,15 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
org.openide.awt.Mnemonics.setLocalizedText(deletedFilesLimitLabel, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.deletedFilesLimitLabel.text")); // NOI18N
+ org.openide.awt.Mnemonics.setLocalizedText(translatedNamesButton, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.translatedNamesButton.text")); // NOI18N
+ translatedNamesButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ translatedNamesButtonActionPerformed(evt);
+ }
+ });
+
+ org.openide.awt.Mnemonics.setLocalizedText(fileDisplayLabel, org.openide.util.NbBundle.getMessage(ViewPreferencesPanel.class, "ViewPreferencesPanel.fileDisplayLabel.text")); // NOI18N
+
javax.swing.GroupLayout globalSettingsPanelLayout = new javax.swing.GroupLayout(globalSettingsPanel);
globalSettingsPanel.setLayout(globalSettingsPanelLayout);
globalSettingsPanelLayout.setHorizontalGroup(
@@ -259,6 +279,8 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
.addComponent(deletedFilesLimitCheckbox, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addGroup(globalSettingsPanelLayout.createSequentialGroup()
.addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(centralRepoLabel)
+ .addComponent(deletedFilesLimitLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 215, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(globalSettingsPanelLayout.createSequentialGroup()
.addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(hideKnownFilesLabel)
@@ -274,9 +296,11 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
.addGap(10, 10, 10)
.addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(dataSourcesHideKnownCheckbox)
- .addComponent(viewsHideKnownCheckbox)))))
+ .addComponent(viewsHideKnownCheckbox))))
+ .addComponent(hideOtherUsersTagsLabel))
.addGap(18, 18, 18)
.addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(fileDisplayLabel)
.addComponent(displayTimeLabel)
.addGroup(globalSettingsPanelLayout.createSequentialGroup()
.addGap(10, 10, 10)
@@ -284,11 +308,9 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
.addComponent(keepCurrentViewerRadioButton)
.addComponent(useBestViewerRadioButton)
.addComponent(useGMTTimeRadioButton)
- .addComponent(useLocalTimeRadioButton)))
- .addComponent(selectFileLabel)))
- .addComponent(hideOtherUsersTagsLabel)
- .addComponent(centralRepoLabel)
- .addComponent(deletedFilesLimitLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 215, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addComponent(useLocalTimeRadioButton)
+ .addComponent(translatedNamesButton)))
+ .addComponent(selectFileLabel))))
.addGap(0, 10, Short.MAX_VALUE)))
.addContainerGap())
);
@@ -322,9 +344,13 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(useGMTTimeRadioButton)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(hideOtherUsersTagsLabel)
+ .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(hideOtherUsersTagsLabel)
+ .addComponent(fileDisplayLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(hideOtherUsersTagsCheckbox)
+ .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(hideOtherUsersTagsCheckbox)
+ .addComponent(translatedNamesButton))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(centralRepoLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
@@ -535,6 +561,14 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
}
}//GEN-LAST:event_deletedFilesLimitCheckboxActionPerformed
+ private void translatedNamesButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_translatedNamesButtonActionPerformed
+ if (immediateUpdates) {
+ UserPreferences.setDisplayTranslationFileNames(translatedNamesButton.isSelected());
+ } else {
+ firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
+ }
+ }//GEN-LAST:event_translatedNamesButtonActionPerformed
+
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel centralRepoLabel;
@@ -546,6 +580,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
private javax.swing.JCheckBox deletedFilesLimitCheckbox;
private javax.swing.JLabel deletedFilesLimitLabel;
private javax.swing.JLabel displayTimeLabel;
+ private javax.swing.JLabel fileDisplayLabel;
private javax.swing.JPanel globalSettingsPanel;
private javax.swing.JCheckBox groupByDataSourceCheckbox;
private javax.swing.JLabel hideKnownFilesLabel;
@@ -555,6 +590,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel {
private javax.swing.JLabel hideSlackFilesLabel;
private javax.swing.JRadioButton keepCurrentViewerRadioButton;
private javax.swing.JLabel selectFileLabel;
+ private javax.swing.JRadioButton translatedNamesButton;
private javax.swing.JRadioButton useBestViewerRadioButton;
private javax.swing.JRadioButton useGMTTimeRadioButton;
private javax.swing.JRadioButton useLocalTimeRadioButton;
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java
index 5f8ea3d63f..2045106a69 100644
--- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java
+++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java
@@ -48,8 +48,13 @@ import org.sleuthkit.autopsy.coreutils.Logger;
import static org.sleuthkit.autopsy.datamodel.AbstractAbstractFileNode.AbstractFilePropertyType.*;
import static org.sleuthkit.autopsy.datamodel.Bundle.*;
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable.HasCommentStatus;
+import org.sleuthkit.autopsy.events.AutopsyEvent;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.ModuleContentEvent;
+import org.sleuthkit.autopsy.texttranslation.NoServiceProviderException;
+import org.sleuthkit.autopsy.texttranslation.TextTranslationService;
+import org.sleuthkit.autopsy.texttranslation.TranslationCallback;
+import org.sleuthkit.autopsy.texttranslation.TranslationException;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.Content;
@@ -70,6 +75,8 @@ public abstract class AbstractAbstractFileNode extends A
private static final Set CASE_EVENTS_OF_INTEREST = EnumSet.of(Case.Events.CURRENT_CASE,
Case.Events.CONTENT_TAG_ADDED, Case.Events.CONTENT_TAG_DELETED, Case.Events.CR_COMMENT_CHANGED);
+
+ private String translateFileName = null;
/**
* @param abstractFile file to wrap
@@ -161,6 +168,9 @@ public abstract class AbstractAbstractFileNode extends A
if (event.getContentID() == content.getId()) {
updateSheet();
}
+ } else if (eventType.equals("TRANSLATION_AVAILABLE")) {
+ setTranslatedSourceName((String) evt.getNewValue());
+ updateSheet();
}
};
@@ -234,7 +244,39 @@ public abstract class AbstractAbstractFileNode extends A
return displayString;
}
}
+
+ public void setTranslatedSourceName(String translation) {
+ translateFileName = translation;
+ }
+
+ public String getTranslatedSourceName(TextTranslationService tts) {
+ if(translateFileName == null) {
+ if(tts.hasProvider()) {
+ tts.translate(this.content.getName(), new TranslationCallback() {
+ @Override
+ public void onTranslation(String translation) {
+ //Talk directy to the nodes PCL, to update when ready.
+ weakPcl.propertyChange(new PropertyChangeEvent(
+ AutopsyEvent.SourceType.LOCAL.toString(),
+ "TRANSLATION_AVAILABLE", "", translation));
+ }
+ @Override
+ public void onTranslationException(TranslationException ex) {
+
+ }
+
+ @Override
+ public void onNoServiceProviderException(NoServiceProviderException ex) {
+ //Do nothing.
+ }
+ });
+ }
+ return "";
+ }
+ return translateFileName;
+ }
+
/**
* Fill map with AbstractFile properties
*
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java
index ef8e1d024e..660957570a 100644
--- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java
+++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java
@@ -27,6 +27,7 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeIns
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil;
import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.coreutils.Logger;
+import org.sleuthkit.autopsy.texttranslation.TextTranslationService;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.ContentTag;
@@ -85,6 +86,12 @@ public abstract class AbstractFsContentNode extends Abst
NO_DESCR,
getName()));
+ TextTranslationService tts = new TextTranslationService();
+ if(UserPreferences.displayTranslationFileNames()) {
+ String translation = getTranslatedSourceName(tts);
+ sheetSet.put(new NodeProperty<>("Translated Name", "Translated Name", "", translation));
+ }
+
addScoreProperty(sheetSet, tags);
//add the comment property before the propertyMap to ensure it is early in column order
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java
index 9a322446bc..7269a09e2c 100644
--- a/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java
+++ b/Core/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java
@@ -320,7 +320,7 @@ public class BlackboardArtifactNode extends AbstractContentNode {
NbBundle.getMessage(this.getClass(), "LayoutFileNode.createSheet.name.desc"),
getName()));
+ TextTranslationService tts = new TextTranslationService();
+ if(tts.hasProvider() && UserPreferences.displayTranslationFileNames()) {
+ String translation = getTranslatedSourceName(tts);
+ sheetSet.put(new NodeProperty<>("Translated Name", "Translated Name", "", translation));
+ }
+
addScoreProperty(sheetSet, tags);
CorrelationAttributeInstance correlationAttribute = null;
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java
index f4146e7a55..53ba3aedbc 100644
--- a/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java
+++ b/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java
@@ -26,6 +26,9 @@ import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil;
import org.sleuthkit.autopsy.core.UserPreferences;
+import org.sleuthkit.autopsy.texttranslation.NoServiceProviderException;
+import org.sleuthkit.autopsy.texttranslation.TextTranslationService;
+import org.sleuthkit.autopsy.texttranslation.TranslationException;
import org.sleuthkit.datamodel.ContentTag;
import org.sleuthkit.datamodel.LocalDirectory;
@@ -66,6 +69,12 @@ public class LocalDirectoryNode extends SpecialDirectoryNode {
Bundle.LocalDirectoryNode_createSheet_name_desc(),
getName()));
+ TextTranslationService tts = new TextTranslationService();
+ if(tts.hasProvider() && UserPreferences.displayTranslationFileNames()) {
+ String translation = getTranslatedSourceName(tts);
+ sheetSet.put(new NodeProperty<>("Translated Name", "Translated Name", "", translation));
+ }
+
addScoreProperty(sheetSet, tags);
CorrelationAttributeInstance correlationAttribute = null;
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java
index 0f69666454..3a75a8a3fb 100644
--- a/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java
+++ b/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java
@@ -42,6 +42,9 @@ import org.sleuthkit.autopsy.directorytree.ExtractAction;
import org.sleuthkit.autopsy.directorytree.NewWindowViewAction;
import org.sleuthkit.autopsy.directorytree.ViewContextAction;
import org.sleuthkit.autopsy.modules.embeddedfileextractor.ExtractArchiveWithPasswordAction;
+import org.sleuthkit.autopsy.texttranslation.NoServiceProviderException;
+import org.sleuthkit.autopsy.texttranslation.TextTranslationService;
+import org.sleuthkit.autopsy.texttranslation.TranslationException;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.ContentTag;
@@ -85,6 +88,19 @@ public class LocalFileNode extends AbstractAbstractFileNode {
NbBundle.getMessage(this.getClass(), "LocalFileNode.createSheet.name.desc"),
getName()));
+ TextTranslationService tts = new TextTranslationService();
+ if(tts.hasProvider() && UserPreferences.displayTranslationFileNames()) {
+ String translation = "";
+ try {
+ translation = tts.translate(this.content.getName());
+ } catch (NoServiceProviderException ex) {
+ //Do nothing, can't happen due to call for hasProvider().
+ } catch (TranslationException ex) {
+ System.out.println(ex);
+ }
+ sheetSet.put(new NodeProperty<>("Translated Name", "Translated Name", "", translation));
+ }
+
addScoreProperty(sheetSet, tags);
CorrelationAttributeInstance correlationAttribute = null;
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java
index 719bc3420a..1b9cdf31a9 100644
--- a/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java
+++ b/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java
@@ -32,6 +32,9 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeIns
import org.sleuthkit.autopsy.centralrepository.datamodel.EamDbUtil;
import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.coreutils.Logger;
+import org.sleuthkit.autopsy.texttranslation.NoServiceProviderException;
+import org.sleuthkit.autopsy.texttranslation.TextTranslationService;
+import org.sleuthkit.autopsy.texttranslation.TranslationException;
import org.sleuthkit.datamodel.ContentTag;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
@@ -92,6 +95,12 @@ public class VirtualDirectoryNode extends SpecialDirectoryNode {
NbBundle.getMessage(this.getClass(), "VirtualDirectoryNode.createSheet.name.desc"),
getName()));
if (!this.content.isDataSource()) {
+ TextTranslationService tts = new TextTranslationService();
+ if(tts.hasProvider() && UserPreferences.displayTranslationFileNames()) {
+ String translation = getTranslatedSourceName(tts);
+ sheetSet.put(new NodeProperty<>("Translated Name", "Translated Name", "", translation));
+ }
+
addScoreProperty(sheetSet, tags);
CorrelationAttributeInstance correlationAttribute = null;
diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java
index 17ee1d078f..17d70834bb 100644
--- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java
+++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java
@@ -170,6 +170,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat
case UserPreferences.HIDE_KNOWN_FILES_IN_DATA_SRCS_TREE:
case UserPreferences.HIDE_SLACK_FILES_IN_DATA_SRCS_TREE:
case UserPreferences.HIDE_CENTRAL_REPO_COMMENTS_AND_OCCURRENCES:
+ case UserPreferences.DISPLAY_TRANSLATED_NAMES:
case UserPreferences.KEEP_PREFERRED_VIEWER:
refreshContentTreeSafe();
break;
diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/NoServiceProviderException.java b/Core/src/org/sleuthkit/autopsy/texttranslation/NoServiceProviderException.java
new file mode 100755
index 0000000000..23bddcc999
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/texttranslation/NoServiceProviderException.java
@@ -0,0 +1,17 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.sleuthkit.autopsy.texttranslation;
+
+/**
+ * Exception to indicate that no Service Provider could be found during the
+ * Lookup action.
+ */
+public class NoServiceProviderException extends Exception {
+
+ public NoServiceProviderException(String msg) {
+ super(msg);
+ }
+}
\ No newline at end of file
diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslationService.java b/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslationService.java
new file mode 100755
index 0000000000..a81ff589ab
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslationService.java
@@ -0,0 +1,89 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2018-2018 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;
+
+import java.util.Optional;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import org.openide.util.Lookup;
+
+/**
+ * Service for finding and running TextTranslator implementations
+ */
+public class TextTranslationService {
+
+ private final Optional translator;
+ private final static ExecutorService pool;
+ private final static Integer MAX_POOL_SIZE = 10;
+
+ static {
+ pool = Executors.newFixedThreadPool(MAX_POOL_SIZE);
+ }
+
+ /**
+ *
+ */
+ public TextTranslationService() {
+ translator = Optional.ofNullable(Lookup.getDefault()
+ .lookup(TextTranslator.class));
+ }
+
+ /**
+ * Performs a lookup for a TextTranslator service provider and if present,
+ * will use this provider to run translation on the input.
+ *
+ * @param input Input string to be translated
+ *
+ * @return Translation string
+ *
+ * @throws NoServiceProviderException Failed to find a Translation service
+ * provider
+ * @throws TranslationException System exception for classes to use
+ * when specific translation
+ * implementations fail
+ */
+ public String translate(String input) throws NoServiceProviderException, TranslationException {
+ if (translator.isPresent()) {
+ return translator.get().translate(input);
+ }
+ throw new NoServiceProviderException(
+ "Could not find a TextTranslator service provider");
+ }
+
+ public void translate(String input, TranslationCallback tcb) {
+ pool.submit(() -> {
+ try {
+ String translation = translate(input);
+ tcb.onTranslation(translation);
+ } catch (NoServiceProviderException ex) {
+ tcb.onNoServiceProviderException(ex);
+ } catch (TranslationException ex) {
+ tcb.onTranslationException(ex);
+ }
+ });
+ }
+
+ /**
+ *
+ * @return
+ */
+ public boolean hasProvider() {
+ return translator.isPresent();
+ }
+}
\ No newline at end of file
diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslator.java b/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslator.java
new file mode 100755
index 0000000000..380f79876e
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslator.java
@@ -0,0 +1,36 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2018-2018 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;
+
+/**
+ * Interface for creating text translators. Implementing classes will be picked
+ * up and run by the Text Translation Service.
+ */
+public interface TextTranslator {
+
+ public String translate(String input) throws TranslationException;
+
+ public default String[] translate(String[] inputs) throws TranslationException {
+ String[] outputs = new String[inputs.length];
+ for(int i = 0; i < inputs.length; i++) {
+ outputs[i] = translate(inputs[i]);
+ }
+ return outputs;
+ }
+}
\ No newline at end of file
diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/TranslationCallback.java b/Core/src/org/sleuthkit/autopsy/texttranslation/TranslationCallback.java
new file mode 100755
index 0000000000..f390a4297c
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/texttranslation/TranslationCallback.java
@@ -0,0 +1,19 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.sleuthkit.autopsy.texttranslation;
+
+/**
+ *
+ * @author dsmyda
+ */
+public interface TranslationCallback {
+
+ public void onTranslation(String translation);
+
+ public void onTranslationException(TranslationException ex);
+
+ public void onNoServiceProviderException(NoServiceProviderException ex);
+}
diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/TranslationException.java b/Core/src/org/sleuthkit/autopsy/texttranslation/TranslationException.java
new file mode 100755
index 0000000000..1fa59123fc
--- /dev/null
+++ b/Core/src/org/sleuthkit/autopsy/texttranslation/TranslationException.java
@@ -0,0 +1,51 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2018-2018 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;
+
+/**
+ * Provides a system exception for the Text Translation errors
+ */
+public class TranslationException extends Exception {
+
+ /**
+ * Constructs a new exception with null as its message.
+ */
+ public TranslationException() {
+ super();
+ }
+
+ /**
+ * Constructs a new exception with the specified message.
+ *
+ * @param message The message.
+ */
+ public TranslationException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a new exception with the specified message and cause.
+ *
+ * @param message The message.
+ * @param cause The cause.
+ */
+ public TranslationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
\ No newline at end of file