From 57db0cd43f8d81f72d66692a86df3eb3000efbfb Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Thu, 25 Oct 2018 11:51:44 -0400 Subject: [PATCH 01/11] Add test translation of file names --- Core/nbproject/project.xml | 1 + .../sleuthkit/autopsy/casemodule/Case.java | 2 +- .../autopsy/core/UserPreferences.java | 11 ++- .../autopsy/corecomponents/Bundle.properties | 2 + .../corecomponents/ViewPreferencesPanel.form | 35 ++++++-- .../corecomponents/ViewPreferencesPanel.java | 52 +++++++++-- .../datamodel/AbstractAbstractFileNode.java | 42 +++++++++ .../datamodel/AbstractFsContentNode.java | 7 ++ .../datamodel/BlackboardArtifactNode.java | 2 +- .../autopsy/datamodel/LayoutFileNode.java | 10 +++ .../autopsy/datamodel/LocalDirectoryNode.java | 9 ++ .../autopsy/datamodel/LocalFileNode.java | 16 ++++ .../datamodel/VirtualDirectoryNode.java | 9 ++ .../DirectoryTreeTopComponent.java | 1 + .../NoServiceProviderException.java | 17 ++++ .../TextTranslationService.java | 89 +++++++++++++++++++ .../texttranslation/TextTranslator.java | 36 ++++++++ .../texttranslation/TranslationCallback.java | 19 ++++ .../texttranslation/TranslationException.java | 51 +++++++++++ 19 files changed, 395 insertions(+), 16 deletions(-) create mode 100755 Core/src/org/sleuthkit/autopsy/texttranslation/NoServiceProviderException.java create mode 100755 Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslationService.java create mode 100755 Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslator.java create mode 100755 Core/src/org/sleuthkit/autopsy/texttranslation/TranslationCallback.java create mode 100755 Core/src/org/sleuthkit/autopsy/texttranslation/TranslationException.java 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 From 4e17668db87613f58522432dcae3366f1e21d95f Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Thu, 25 Oct 2018 14:32:11 -0400 Subject: [PATCH 02/11] Added some comments and move stuff around to make it clearer --- .../corecomponents/ViewPreferencesPanel.java | 4 +- .../datamodel/AbstractAbstractFileNode.java | 147 +++++++++++++----- .../datamodel/AbstractFsContentNode.java | 5 +- .../autopsy/datamodel/LayoutFileNode.java | 5 +- .../autopsy/datamodel/LocalDirectoryNode.java | 5 +- .../autopsy/datamodel/LocalFileNode.java | 12 +- .../datamodel/VirtualDirectoryNode.java | 5 +- .../NoServiceProviderException.java | 19 ++- .../TextTranslationService.java | 74 +++++---- .../texttranslation/TextTranslator.java | 7 - .../texttranslation/TranslationCallback.java | 37 ++++- 11 files changed, 218 insertions(+), 102 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java index 2d7cb019c8..4a9fce6f8d 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java @@ -46,8 +46,8 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { initComponents(); this.immediateUpdates = immediateUpdates; - TextTranslationService translationService = new TextTranslationService(); - if(!translationService.hasProvider()) { + TextTranslationService tts = new TextTranslationService(); + if(!tts.hasProvider()) { translatedNamesButton.setVisible(false); fileDisplayLabel.setVisible(false); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index 2045106a69..276b67a37b 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -27,6 +27,7 @@ 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.openide.nodes.Children; import org.openide.nodes.Sheet; @@ -72,11 +73,14 @@ public abstract class AbstractAbstractFileNode extends A private static final Logger logger = Logger.getLogger(AbstractAbstractFileNode.class.getName()); @NbBundle.Messages("AbstractAbstractFileNode.addFileProperty.desc=no description") private static final String NO_DESCR = AbstractAbstractFileNode_addFileProperty_desc(); + + private static final String TRANSLATION_AVAILABLE_EVENT = "TRANSLATION_AVAILABLE"; + private static final String NO_TRANSLATION = ""; 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; + + private String translatedFileName; /** * @param abstractFile file to wrap @@ -92,6 +96,7 @@ public abstract class AbstractAbstractFileNode extends A IngestManager.getInstance().addIngestModuleEventListener(weakPcl); } } + translatedFileName = null; // Listen for case events so that we can detect when the case is closed // or when tags are added. Case.addEventTypeSubscriber(CASE_EVENTS_OF_INTEREST, weakPcl); @@ -168,8 +173,8 @@ public abstract class AbstractAbstractFileNode extends A if (event.getContentID() == content.getId()) { updateSheet(); } - } else if (eventType.equals("TRANSLATION_AVAILABLE")) { - setTranslatedSourceName((String) evt.getNewValue()); + } else if (eventType.equals(TRANSLATION_AVAILABLE_EVENT)) { + this.translatedFileName = (String) evt.getNewValue(); updateSheet(); } }; @@ -244,39 +249,43 @@ 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 ""; + /** + * Attempts translation on the file name by kicking off a background task to do the + * translation. Once the background task is done, it will fire a PropertyChangeEvent, + * which will force this node to refresh itself, thus updating its translated name + * column. + * + * @return The file names translation. + */ + protected String getTranslatedFileName() { + //If already in complete English, don't translate. + if (this.content.getName().matches("^\\p{ASCII}+$")) { + return NO_TRANSLATION; } - return translateFileName; + + //If we already have a translation use that one. + if (translatedFileName != null) { + return translatedFileName; + } + + //If not, lets fire off a background translation that will update the UI + //when it is done. + TextTranslationService tts = new TextTranslationService(); + if (tts.hasProvider()) { + //Seperate out the base and ext from the contents file name. + String base = FilenameUtils.getBaseName(this.content.getName()); + String ext = FilenameUtils.getExtension(this.content.getName()); + + //Send only the base file name to be translated. Once the translation comes + //back fire a PropertyChangeEvent on this nodes PropertyChangeListener. + tts.translateAsynchronously(base, new TranslateFileNameCallback(ext, weakPcl)); + } + + //In the mean time, return a blank translation. + return NO_TRANSLATION; } - + /** * Fill map with AbstractFile properties * @@ -431,7 +440,7 @@ public abstract class AbstractAbstractFileNode extends A } catch (CorrelationAttributeNormalizationException ex) { logger.log(Level.WARNING, "Unable to normalize data to get count of datasources with correlation attribute", ex); } - + sheetSet.put( new NodeProperty<>(Bundle.AbstractAbstractFileNode_createSheet_count_name(), Bundle.AbstractAbstractFileNode_createSheet_count_displayName(), description, count)); } @@ -442,6 +451,7 @@ public abstract class AbstractAbstractFileNode extends A * * @param sheetSet the modifiable Sheet.Set returned by * Sheet.get(Sheet.PROPERTIES) + * * @deprecated */ @NbBundle.Messages("AbstractAbstractFileNode.tagsProperty.displayName=Tags") @@ -488,6 +498,7 @@ public abstract class AbstractAbstractFileNode extends A * @param file The file. * * @return The CSV list of hash set names. + * * @deprecated */ @Deprecated @@ -499,4 +510,70 @@ public abstract class AbstractAbstractFileNode extends A return ""; } } + + /** + * Implements the TranslationCallback interface so that the TextTranslationService + * can call these methods when an asynchronous translation task is complete. + */ + private class TranslateFileNameCallback implements TranslationCallback { + //Seperate out the base and ext from the contents file name. + private final String ext; + + private final PropertyChangeListener listener; + + public TranslateFileNameCallback(String ext, PropertyChangeListener listener) { + this.ext = ext; + this.listener = listener; + } + + /** + * Fires a PropertyChangeEvent on this nodes PropertyChangeListener + * when the translation is finished. Reconstruct the file name so we + * can properly display the translation. + * + * @param translation Result from the translation job submitted to + * Text translation service. + */ + @Override + public void onTranslationResult(String translation) { + //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()) { + listener.propertyChange(new PropertyChangeEvent( + AutopsyEvent.SourceType.LOCAL.toString(), + TRANSLATION_AVAILABLE_EVENT, null, translation)); + } else { + listener.propertyChange(new PropertyChangeEvent( + AutopsyEvent.SourceType.LOCAL.toString(), + TRANSLATION_AVAILABLE_EVENT, null, + translation + extensionDelimiter + ext)); + } + } + + /** + * Do nothing on a translation exception, the column will remain empty + * and there is nothing we can do as a fallback. + * + * @param ex Exception caught while translating. + */ + @Override + public void onTranslationException(TranslationException ex) { + //Do nothing + } + + /** + * Do nothing on a no service provider exception, in this implemention we + * are only calling for translation to be done if we know that a TextTranslator + * service provider is already defined. + * + * @param ex + */ + @Override + public void onNoServiceProviderException(NoServiceProviderException ex) { + //Do nothing + } + } } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java index 660957570a..ed0eb09b8d 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java @@ -85,10 +85,9 @@ public abstract class AbstractFsContentNode extends Abst AbstractFilePropertyType.NAME.toString(), NO_DESCR, getName())); - - TextTranslationService tts = new TextTranslationService(); + if(UserPreferences.displayTranslationFileNames()) { - String translation = getTranslatedSourceName(tts); + String translation = getTranslatedFileName(); sheetSet.put(new NodeProperty<>("Translated Name", "Translated Name", "", translation)); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java index c70e8675d7..56c77d0acd 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java @@ -98,9 +98,8 @@ public class LayoutFileNode extends AbstractAbstractFileNode { NbBundle.getMessage(this.getClass(), "LayoutFileNode.createSheet.name.desc"), getName())); - TextTranslationService tts = new TextTranslationService(); - if(tts.hasProvider() && UserPreferences.displayTranslationFileNames()) { - String translation = getTranslatedSourceName(tts); + if(UserPreferences.displayTranslationFileNames()) { + String translation = getTranslatedFileName(); sheetSet.put(new NodeProperty<>("Translated Name", "Translated Name", "", translation)); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java index 53ba3aedbc..8cd255fd5d 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java @@ -69,9 +69,8 @@ public class LocalDirectoryNode extends SpecialDirectoryNode { Bundle.LocalDirectoryNode_createSheet_name_desc(), getName())); - TextTranslationService tts = new TextTranslationService(); - if(tts.hasProvider() && UserPreferences.displayTranslationFileNames()) { - String translation = getTranslatedSourceName(tts); + if(UserPreferences.displayTranslationFileNames()) { + String translation = getTranslatedFileName(); sheetSet.put(new NodeProperty<>("Translated Name", "Translated Name", "", translation)); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java index 3a75a8a3fb..ddbc0dd4ae 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java @@ -88,16 +88,8 @@ 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); - } + if(UserPreferences.displayTranslationFileNames()) { + String translation = getTranslatedFileName(); sheetSet.put(new NodeProperty<>("Translated Name", "Translated Name", "", translation)); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java index 1b9cdf31a9..8de2db173a 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java @@ -95,9 +95,8 @@ 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); + if(UserPreferences.displayTranslationFileNames()) { + String translation = getTranslatedFileName(); sheetSet.put(new NodeProperty<>("Translated Name", "Translated Name", "", translation)); } diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/NoServiceProviderException.java b/Core/src/org/sleuthkit/autopsy/texttranslation/NoServiceProviderException.java index 23bddcc999..79590fcfd9 100755 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/NoServiceProviderException.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/NoServiceProviderException.java @@ -1,7 +1,20 @@ /* - * 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. + * 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; diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslationService.java b/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslationService.java index a81ff589ab..4e35734781 100755 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslationService.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslationService.java @@ -18,28 +18,25 @@ */ package org.sleuthkit.autopsy.texttranslation; +import com.google.common.util.concurrent.ThreadFactoryBuilder; import java.util.Optional; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; import org.openide.util.Lookup; /** * Service for finding and running TextTranslator implementations */ public class TextTranslationService { + + private final static Optional translator; - private final Optional translator; - private final static ExecutorService pool; + private static ExecutorService pool; private final static Integer MAX_POOL_SIZE = 10; - + static { - pool = Executors.newFixedThreadPool(MAX_POOL_SIZE); - } - - /** - * - */ - public TextTranslationService() { + //Perform look up for Text Translation implementations translator = Optional.ofNullable(Lookup.getDefault() .lookup(TextTranslator.class)); } @@ -65,25 +62,48 @@ public class TextTranslationService { 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 + * Allows the translation task to happen asynchronously, promising to use + * the TranslationCallback methods when the translation is complete. + * + * @param input + * @param tcb + */ + public void translateAsynchronously(String input, TranslationCallback tcb) { + if(translator.isPresent()) { + //Delay thread pool initialization until an asynchronous task is first called. + //That way we don't have threads sitting parked in the background for no reason. + if (pool == null) { + ThreadFactory translationFactory = new ThreadFactoryBuilder() + .setNameFormat("translation-thread-%d") + .build(); + pool = Executors.newFixedThreadPool(MAX_POOL_SIZE, translationFactory); + } + + pool.submit(() -> { + try { + String translation = translate(input); + tcb.onTranslationResult(translation); + } catch (NoServiceProviderException ex) { + tcb.onNoServiceProviderException(ex); + } catch (TranslationException ex) { + tcb.onTranslationException(ex); + } + }); + } + + tcb.onNoServiceProviderException(new NoServiceProviderException( + "Could not find a TextTranslator service provider")); + } + + /** + * Returns if a TextTranslator lookup successfully found an implementing + * class. + * + * @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 index 380f79876e..4a813ed6cc 100755 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslator.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslator.java @@ -26,11 +26,4 @@ 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 index f390a4297c..4cbdb79265 100755 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/TranslationCallback.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/TranslationCallback.java @@ -1,19 +1,44 @@ /* - * 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. + * 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; /** - * - * @author dsmyda + * Provides a way for translation results to be processed when they are + * */ public interface TranslationCallback { - public void onTranslation(String translation); + /** + * + * @param translation + */ + public void onTranslationResult(String translation); + /** + * + * @param ex + */ public void onTranslationException(TranslationException ex); + /** + * + * @param ex + */ public void onNoServiceProviderException(NoServiceProviderException ex); } From 7401fbe32caa7dd7cd8bc9b1394e4390c8e85674 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Thu, 25 Oct 2018 15:17:22 -0400 Subject: [PATCH 03/11] Added some comments --- .../corecomponents/ViewPreferencesPanel.java | 2 ++ .../TextTranslationService.java | 35 +++++++++++-------- .../texttranslation/TranslationCallback.java | 11 ++++-- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java index 4a9fce6f8d..c6bc396fbe 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java @@ -46,6 +46,8 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { initComponents(); this.immediateUpdates = immediateUpdates; + //If there is not Text Translator implementation, then hide these buttons + //from the user. TextTranslationService tts = new TextTranslationService(); if(!tts.hasProvider()) { translatedNamesButton.setVisible(false); diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslationService.java b/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslationService.java index 4e35734781..bac1ee9fb3 100755 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslationService.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslationService.java @@ -31,7 +31,7 @@ import org.openide.util.Lookup; public class TextTranslationService { private final static Optional translator; - + private static ExecutorService pool; private final static Integer MAX_POOL_SIZE = 10; @@ -42,8 +42,8 @@ public class TextTranslationService { } /** - * Performs a lookup for a TextTranslator service provider and if present, - * will use this provider to run translation on the input. + * Translates the input string using whichever TextTranslator Service Provider + * was found during lookup. * * @param input Input string to be translated * @@ -64,23 +64,28 @@ public class TextTranslationService { } /** - * Allows the translation task to happen asynchronously, promising to use - * the TranslationCallback methods when the translation is complete. + * Makes the call to translate(String) happen asynchronously on a background + * thread. When it is done, it will use the appropriate TranslationCallback + * method. + * + * @param input String to be translated + * @param tcb Interface for handling the translation result or any + * exceptions thrown while running translate. * - * @param input - * @param tcb */ public void translateAsynchronously(String input, TranslationCallback tcb) { - if(translator.isPresent()) { + if (translator.isPresent()) { //Delay thread pool initialization until an asynchronous task is first called. //That way we don't have threads sitting parked in the background for no reason. if (pool == null) { ThreadFactory translationFactory = new ThreadFactoryBuilder() - .setNameFormat("translation-thread-%d") - .build(); + .setNameFormat("translation-thread-%d") + .build(); pool = Executors.newFixedThreadPool(MAX_POOL_SIZE, translationFactory); } - + + //Submit the task to the pool, calling the appropriate method depending + //on the result of the translate operation. pool.submit(() -> { try { String translation = translate(input); @@ -91,17 +96,17 @@ public class TextTranslationService { tcb.onTranslationException(ex); } }); - } - + } + tcb.onNoServiceProviderException(new NoServiceProviderException( "Could not find a TextTranslator service provider")); } /** - * Returns if a TextTranslator lookup successfully found an implementing + * Returns if a TextTranslator lookup successfully found an implementing * class. * - * @return + * @return */ public boolean hasProvider() { return translator.isPresent(); diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/TranslationCallback.java b/Core/src/org/sleuthkit/autopsy/texttranslation/TranslationCallback.java index 4cbdb79265..c38617cbab 100755 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/TranslationCallback.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/TranslationCallback.java @@ -19,24 +19,29 @@ package org.sleuthkit.autopsy.texttranslation; /** - * Provides a way for translation results to be processed when they are - * + * This callback interface will be used by TextTranslationService when doing + * translations on background tasks. When the translation is done, it's result will + * be delegated to one of the following methods. It can either be successful or fail with + * exceptions. */ public interface TranslationCallback { /** + * Provides a method to handle the translation result * - * @param translation + * @param translation result of calling TextTranslationService. */ public void onTranslationResult(String translation); /** + * Provides a way to handle Translation Exceptions. * * @param ex */ public void onTranslationException(TranslationException ex); /** + * Provides a way to handle NoServiceProviderExceptions. * * @param ex */ From 7e97e5e195c17ffde8e4c8daf61c8ccbd10db46d Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Thu, 25 Oct 2018 15:18:38 -0400 Subject: [PATCH 04/11] reverted space is case.java --- Core/src/org/sleuthkit/autopsy/casemodule/Case.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java index b5624f8fa2..dcb2af3eef 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. From f9606deea7706e9f231a612b7b0ef3df07eb2db5 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Thu, 25 Oct 2018 15:32:14 -0400 Subject: [PATCH 05/11] Added log message in --- .../datamodel/AbstractAbstractFileNode.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index 276b67a37b..aef33be3ad 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -275,11 +275,10 @@ public abstract class AbstractAbstractFileNode extends A if (tts.hasProvider()) { //Seperate out the base and ext from the contents file name. String base = FilenameUtils.getBaseName(this.content.getName()); - String ext = FilenameUtils.getExtension(this.content.getName()); //Send only the base file name to be translated. Once the translation comes //back fire a PropertyChangeEvent on this nodes PropertyChangeListener. - tts.translateAsynchronously(base, new TranslateFileNameCallback(ext, weakPcl)); + tts.translateAsynchronously(base, new TranslateFileNameCallback(this.content, weakPcl)); } //In the mean time, return a blank translation. @@ -518,11 +517,13 @@ public abstract class AbstractAbstractFileNode extends A private class TranslateFileNameCallback implements TranslationCallback { //Seperate out the base and ext from the contents file name. private final String ext; + private final String originalFileName; private final PropertyChangeListener listener; - public TranslateFileNameCallback(String ext, PropertyChangeListener listener) { - this.ext = ext; + public TranslateFileNameCallback(AbstractFile file, PropertyChangeListener listener) { + this.ext = FilenameUtils.getExtension(content.getName()); + this.originalFileName = content.getName(); this.listener = listener; } @@ -554,18 +555,18 @@ public abstract class AbstractAbstractFileNode extends A } /** - * Do nothing on a translation exception, the column will remain empty + * Do nothing on a translation exception except log, the column will remain empty * and there is nothing we can do as a fallback. * * @param ex Exception caught while translating. */ @Override public void onTranslationException(TranslationException ex) { - //Do nothing + logger.log(Level.WARNING, "Could not successfully translate file name " + originalFileName, ex); } /** - * Do nothing on a no service provider exception, in this implemention we + * Do nothing on a no service provider exception except log, in this implemention we * are only calling for translation to be done if we know that a TextTranslator * service provider is already defined. * @@ -573,7 +574,8 @@ public abstract class AbstractAbstractFileNode extends A */ @Override public void onNoServiceProviderException(NoServiceProviderException ex) { - //Do nothing + logger.log(Level.WARNING, "Translate unsuccessful because no TextTranslator " + + "implementation was provided.", ex); } } } From cefbafa63c0572e3e0e0a90e8f2d2a469f1ac6ba Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Thu, 25 Oct 2018 15:39:52 -0400 Subject: [PATCH 06/11] Made the labels all point to the same bundle message --- .../autopsy/datamodel/AbstractAbstractFileNode.java | 2 +- .../autopsy/datamodel/AbstractFsContentNode.java | 3 ++- .../org/sleuthkit/autopsy/datamodel/LayoutFileNode.java | 7 +++++-- .../org/sleuthkit/autopsy/datamodel/LocalFileNode.java | 8 +++----- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index aef33be3ad..2516a92419 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -194,6 +194,7 @@ public abstract class AbstractAbstractFileNode extends A } @NbBundle.Messages({"AbstractAbstractFileNode.nameColLbl=Name", + "AbstractAbstractFileNode.translateFileName=Translated Name", "AbstractAbstractFileNode.locationColLbl=Location", "AbstractAbstractFileNode.modifiedTimeColLbl=Modified Time", "AbstractAbstractFileNode.changeTimeColLbl=Change Time", @@ -515,7 +516,6 @@ public abstract class AbstractAbstractFileNode extends A * can call these methods when an asynchronous translation task is complete. */ private class TranslateFileNameCallback implements TranslationCallback { - //Seperate out the base and ext from the contents file name. private final String ext; private final String originalFileName; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java index ed0eb09b8d..996977fabc 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java @@ -88,7 +88,8 @@ public abstract class AbstractFsContentNode extends Abst if(UserPreferences.displayTranslationFileNames()) { String translation = getTranslatedFileName(); - sheetSet.put(new NodeProperty<>("Translated Name", "Translated Name", "", translation)); + sheetSet.put(new NodeProperty<>(Bundle.AbstractAbstractFileNode_translateFileName(), + Bundle.AbstractAbstractFileNode_translateFileName(), NO_DESCR, translation)); } addScoreProperty(sheetSet, tags); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java index 56c77d0acd..fa3c2f3b56 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java @@ -98,9 +98,12 @@ public class LayoutFileNode extends AbstractAbstractFileNode { NbBundle.getMessage(this.getClass(), "LayoutFileNode.createSheet.name.desc"), getName())); + final String NO_DESCR = NbBundle.getMessage(this.getClass(), "LayoutFileNode.createSheet.noDescr.text"); + if(UserPreferences.displayTranslationFileNames()) { String translation = getTranslatedFileName(); - sheetSet.put(new NodeProperty<>("Translated Name", "Translated Name", "", translation)); + sheetSet.put(new NodeProperty<>(Bundle.AbstractAbstractFileNode_translateFileName(), + Bundle.AbstractAbstractFileNode_translateFileName(), NO_DESCR, translation)); } addScoreProperty(sheetSet, tags); @@ -114,7 +117,7 @@ public class LayoutFileNode extends AbstractAbstractFileNode { if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoCommentsAndOccurrences() == false) { addCountProperty(sheetSet, correlationAttribute); } - final String NO_DESCR = NbBundle.getMessage(this.getClass(), "LayoutFileNode.createSheet.noDescr.text"); + for (Map.Entry entry : map.entrySet()) { sheetSet.put(new NodeProperty<>(entry.getKey(), entry.getKey(), NO_DESCR, entry.getValue())); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java index ddbc0dd4ae..7ca92d5ee5 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/LocalFileNode.java @@ -42,9 +42,6 @@ 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; @@ -88,9 +85,11 @@ public class LocalFileNode extends AbstractAbstractFileNode { NbBundle.getMessage(this.getClass(), "LocalFileNode.createSheet.name.desc"), getName())); + final String NO_DESCR = NbBundle.getMessage(this.getClass(), "LocalFileNode.createSheet.noDescr.text"); if(UserPreferences.displayTranslationFileNames()) { String translation = getTranslatedFileName(); - sheetSet.put(new NodeProperty<>("Translated Name", "Translated Name", "", translation)); + sheetSet.put(new NodeProperty<>(Bundle.AbstractAbstractFileNode_translateFileName(), + Bundle.AbstractAbstractFileNode_translateFileName(), NO_DESCR, translation)); } addScoreProperty(sheetSet, tags); @@ -104,7 +103,6 @@ public class LocalFileNode extends AbstractAbstractFileNode { if (EamDbUtil.useCentralRepo() && UserPreferences.hideCentralRepoCommentsAndOccurrences() == false) { addCountProperty(sheetSet, correlationAttribute); } - final String NO_DESCR = NbBundle.getMessage(this.getClass(), "LocalFileNode.createSheet.noDescr.text"); for (Map.Entry entry : map.entrySet()) { sheetSet.put(new NodeProperty<>(entry.getKey(), entry.getKey(), NO_DESCR, entry.getValue())); } From 1f3c2d2f0bf0c03787617efcdce8922761ce2b93 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Thu, 25 Oct 2018 15:40:51 -0400 Subject: [PATCH 07/11] Removed unused imports --- .../sleuthkit/autopsy/datamodel/AbstractFsContentNode.java | 1 - Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java | 4 ---- 2 files changed, 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java index 996977fabc..cd88832e54 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractFsContentNode.java @@ -27,7 +27,6 @@ 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; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java index fa3c2f3b56..3703030e8e 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/LayoutFileNode.java @@ -27,7 +27,6 @@ import java.util.List; import java.util.Map; import javax.swing.Action; import org.openide.nodes.Sheet; -import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.util.Utilities; import org.sleuthkit.autopsy.actions.AddContentTagAction; @@ -39,9 +38,6 @@ import org.sleuthkit.autopsy.coreutils.ContextMenuExtensionPoint; import org.sleuthkit.autopsy.directorytree.ExternalViewerAction; import org.sleuthkit.autopsy.directorytree.ExtractAction; import org.sleuthkit.autopsy.directorytree.NewWindowViewAction; -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.ContentTag; import org.sleuthkit.datamodel.LayoutFile; From 0edda0d0ae1e4651da4fa36b81cf53d2d5cf1b88 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Fri, 26 Oct 2018 08:47:52 -0400 Subject: [PATCH 08/11] Did codacy suggestions --- .../autopsy/datamodel/AbstractAbstractFileNode.java | 8 ++++---- .../autopsy/datamodel/LocalDirectoryNode.java | 3 --- .../autopsy/datamodel/VirtualDirectoryNode.java | 3 --- .../autopsy/texttranslation/TextTranslator.java | 2 +- .../autopsy/texttranslation/TranslationCallback.java | 10 +++++----- 5 files changed, 10 insertions(+), 16 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index 2516a92419..1f32cc554b 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -561,8 +561,8 @@ public abstract class AbstractAbstractFileNode extends A * @param ex Exception caught while translating. */ @Override - public void onTranslationException(TranslationException ex) { - logger.log(Level.WARNING, "Could not successfully translate file name " + originalFileName, ex); + public void onTranslationException(TranslationException noTranslationEx) { + logger.log(Level.WARNING, "Could not successfully translate file name " + originalFileName, noTranslationEx); } /** @@ -573,9 +573,9 @@ public abstract class AbstractAbstractFileNode extends A * @param ex */ @Override - public void onNoServiceProviderException(NoServiceProviderException ex) { + public void onNoServiceProviderException(NoServiceProviderException noServiceEx) { logger.log(Level.WARNING, "Translate unsuccessful because no TextTranslator " - + "implementation was provided.", ex); + + "implementation was provided.", noServiceEx); } } } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java index 8cd255fd5d..1a80fb2737 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java @@ -26,9 +26,6 @@ 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; diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java index 8de2db173a..6c6a4f6f1a 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/VirtualDirectoryNode.java @@ -32,9 +32,6 @@ 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; diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslator.java b/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslator.java index 4a813ed6cc..33be6d04ca 100755 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslator.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslator.java @@ -24,6 +24,6 @@ package org.sleuthkit.autopsy.texttranslation; */ public interface TextTranslator { - public String translate(String input) throws TranslationException; + String translate(String input) throws TranslationException; } \ 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 index c38617cbab..8144f6fa1f 100755 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/TranslationCallback.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/TranslationCallback.java @@ -31,19 +31,19 @@ public interface TranslationCallback { * * @param translation result of calling TextTranslationService. */ - public void onTranslationResult(String translation); + void onTranslationResult(String translation); /** * Provides a way to handle Translation Exceptions. * - * @param ex + * @param noTranslationEx */ - public void onTranslationException(TranslationException ex); + void onTranslationException(TranslationException noTranslationEx); /** * Provides a way to handle NoServiceProviderExceptions. * - * @param ex + * @param noServiceEx */ - public void onNoServiceProviderException(NoServiceProviderException ex); + void onNoServiceProviderException(NoServiceProviderException noServiceEx); } From 5e817a63e5e7df67a57120be59786b77a6cdb224 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Fri, 26 Oct 2018 08:59:26 -0400 Subject: [PATCH 09/11] Made TextTranslationService a singleton --- .../corecomponents/ViewPreferencesPanel.java | 2 +- .../datamodel/AbstractAbstractFileNode.java | 2 +- .../texttranslation/TextTranslationService.java | 15 +++++++++++---- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java index c6bc396fbe..e65302db7f 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java @@ -48,7 +48,7 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { //If there is not Text Translator implementation, then hide these buttons //from the user. - TextTranslationService tts = new TextTranslationService(); + TextTranslationService tts = TextTranslationService.getInstance(); if(!tts.hasProvider()) { translatedNamesButton.setVisible(false); fileDisplayLabel.setVisible(false); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java index 1f32cc554b..a63f441a2b 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/AbstractAbstractFileNode.java @@ -272,7 +272,7 @@ public abstract class AbstractAbstractFileNode extends A //If not, lets fire off a background translation that will update the UI //when it is done. - TextTranslationService tts = new TextTranslationService(); + TextTranslationService tts = TextTranslationService.getInstance(); if (tts.hasProvider()) { //Seperate out the base and ext from the contents file name. String base = FilenameUtils.getBaseName(this.content.getName()); diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslationService.java b/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslationService.java index bac1ee9fb3..fb33425a8f 100755 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslationService.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslationService.java @@ -29,17 +29,24 @@ import org.openide.util.Lookup; * Service for finding and running TextTranslator implementations */ public class TextTranslationService { + + private final static TextTranslationService tts = new TextTranslationService(); - private final static Optional translator; + private final Optional translator; private static ExecutorService pool; private final static Integer MAX_POOL_SIZE = 10; - - static { - //Perform look up for Text Translation implementations + + private TextTranslationService(){ + //Perform look up for Text Translation implementations ONLY ONCE during + //class loading. translator = Optional.ofNullable(Lookup.getDefault() .lookup(TextTranslator.class)); } + + public static TextTranslationService getInstance() { + return tts; + } /** * Translates the input string using whichever TextTranslator Service Provider From af192b2c1d54ec3e44ff6586f734d1f6f176ebab Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Fri, 26 Oct 2018 09:13:48 -0400 Subject: [PATCH 10/11] Changed panel text according to Brian's request --- .../org/sleuthkit/autopsy/corecomponents/Bundle.properties | 4 ++-- .../autopsy/corecomponents/ViewPreferencesPanel.form | 4 ++-- .../autopsy/corecomponents/ViewPreferencesPanel.java | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties index efd861fb24..3e8e75dad7 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/Bundle.properties @@ -192,5 +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 +ViewPreferencesPanel.fileDisplayLabel.text=Translate text in the: +ViewPreferencesPanel.translatedNamesButton.text=Table diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form index 096c24af11..1f76dde4dd 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.form @@ -176,9 +176,9 @@ - - + + diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java index e65302db7f..af9a940537 100755 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/ViewPreferencesPanel.java @@ -346,9 +346,9 @@ public class ViewPreferencesPanel extends JPanel implements OptionsPanel { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(useGMTTimeRadioButton))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(hideOtherUsersTagsLabel) - .addComponent(fileDisplayLabel)) + .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(fileDisplayLabel) + .addComponent(hideOtherUsersTagsLabel)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(globalSettingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(hideOtherUsersTagsCheckbox) From 95b981c99115fa7bd727a79ae265118df26facb1 Mon Sep 17 00:00:00 2001 From: "U-BASIS\\dsmyda" Date: Mon, 29 Oct 2018 09:01:51 -0400 Subject: [PATCH 11/11] Final codacy issues --- .../org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java | 5 +++-- .../autopsy/texttranslation/TextTranslationService.java | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java index 1a80fb2737..bd59e8ca67 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/LocalDirectoryNode.java @@ -66,9 +66,11 @@ public class LocalDirectoryNode extends SpecialDirectoryNode { Bundle.LocalDirectoryNode_createSheet_name_desc(), getName())); + final String NO_DESCR = Bundle.LocalDirectoryNode_createSheet_noDesc(); if(UserPreferences.displayTranslationFileNames()) { String translation = getTranslatedFileName(); - sheetSet.put(new NodeProperty<>("Translated Name", "Translated Name", "", translation)); + sheetSet.put(new NodeProperty<>(Bundle.AbstractAbstractFileNode_translateFileName(), + Bundle.AbstractAbstractFileNode_translateFileName(), NO_DESCR, translation)); } addScoreProperty(sheetSet, tags); @@ -87,7 +89,6 @@ public class LocalDirectoryNode extends SpecialDirectoryNode { Map map = new LinkedHashMap<>(); fillPropertyMap(map, getContent()); - final String NO_DESCR = Bundle.LocalDirectoryNode_createSheet_noDesc(); for (Map.Entry entry : map.entrySet()) { sheetSet.put(new NodeProperty<>(entry.getKey(), entry.getKey(), NO_DESCR, entry.getValue())); } diff --git a/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslationService.java b/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslationService.java index fb33425a8f..04e4e07835 100755 --- a/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslationService.java +++ b/Core/src/org/sleuthkit/autopsy/texttranslation/TextTranslationService.java @@ -28,7 +28,7 @@ import org.openide.util.Lookup; /** * Service for finding and running TextTranslator implementations */ -public class TextTranslationService { +public final class TextTranslationService { private final static TextTranslationService tts = new TextTranslationService();