Autopsy  4.20.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
TranslateTextTask.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2020 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.texttranslation.ui;
20 
21 import java.awt.ComponentOrientation;
22 import java.awt.Font;
23 import java.io.IOException;
24 import java.util.concurrent.CancellationException;
25 import java.util.concurrent.ExecutionException;
26 import java.util.logging.Level;
27 import javax.swing.SwingUtilities;
28 import javax.swing.SwingWorker;
29 import org.openide.util.NbBundle;
35 
39 public abstract class TranslateTextTask extends SwingWorker<TranslateTextTask.TranslateResult, Void> {
40 
41  private static final Logger logger = Logger.getLogger(TranslatedTextViewer.class.getName());
42 
43  private final boolean translateText;
44  private final String contentDescriptor;
45 
49  public static class TranslateResult {
50 
51  private final String errorMessage;
52  private final String result;
53  private final boolean successful;
54 
55  public static TranslateResult error(String message) {
56  return new TranslateResult(null, message, false);
57  }
58 
59  public static TranslateResult success(String content) {
60  return new TranslateResult(content, null, true);
61  }
62 
63  private TranslateResult(String result, String errorMessage, boolean successful) {
64  this.successful = successful;
65  this.errorMessage = errorMessage;
66  this.result = result;
67  }
68 
69  public String getErrorMessage() {
70  return errorMessage;
71  }
72 
73  public String getResult() {
74  return result;
75  }
76 
77  public boolean isSuccessful() {
78  return successful;
79  }
80 
81  }
82 
89  public TranslateTextTask(boolean translateText, String fileDescriptor) {
90  this.translateText = translateText;
91  this.contentDescriptor = fileDescriptor;
92  }
93 
101  protected abstract String retrieveText() throws IOException, InterruptedException, IllegalStateException;
102 
109  protected abstract void onTextDisplay(String text, ComponentOrientation orientation, int font);
110 
118  protected void onProgressDisplay(String text, ComponentOrientation orientation, int font) {
119  // This defaults to normal display unless overridden.
120  onTextDisplay(text, orientation, font);
121  }
122 
130  protected void onErrorDisplay(String text, ComponentOrientation orientation, int font) {
131  // This defaults to normal display unless overridden.
132  onTextDisplay(text, orientation, font);
133  }
134 
135  @NbBundle.Messages({
136  "TranslatedContentViewer.translatingText=Translating text, please wait...",
137  "TranslatedContentViewer.fileHasNoText=File has no text.",
138  "TranslatedContentViewer.noServiceProvider=The machine translation software was not found.",
139  "# {0} - exception message", "TranslatedContentViewer.translationException=An error occurred while translating the text ({0})."
140  })
141  @Override
142  public TranslateResult doInBackground() throws InterruptedException {
143  if (this.isCancelled()) {
144  throw new InterruptedException();
145  }
146 
147  String fileText;
148  try {
149  fileText = retrieveText();
150  } catch (IOException | IllegalStateException ex) {
151  return TranslateResult.error(ex.getMessage());
152  }
153 
154  if (this.isCancelled()) {
155  throw new InterruptedException();
156  }
157 
158  if (fileText == null || fileText.isEmpty()) {
159  return TranslateResult.error(Bundle.TranslatedContentViewer_fileHasNoText());
160  }
161 
162  if (!this.translateText) {
163  return TranslateResult.success(fileText);
164  }
165 
166  return translateRetrievedText(fileText);
167  }
168 
175  private TranslateResult translateRetrievedText(String fileText) throws InterruptedException {
176  SwingUtilities.invokeLater(() -> {
177  onProgressDisplay(Bundle.TranslatedContentViewer_translatingText(), ComponentOrientation.LEFT_TO_RIGHT, Font.ITALIC);
178  });
179 
180  try {
181  String translation = translate(fileText);
182  if (this.isCancelled()) {
183  throw new InterruptedException();
184  }
185 
186  if (translation == null || translation.isEmpty()) {
187  return TranslateResult.error(Bundle.TranslatedContentViewer_emptyTranslation());
188  } else {
189  return TranslateResult.success(translation);
190  }
191 
192  } catch (NoServiceProviderException ex) {
193  logger.log(Level.WARNING, "Error translating text for file " + this.contentDescriptor, ex);
194  return TranslateResult.error(Bundle.TranslatedContentViewer_noServiceProvider());
195  } catch (TranslationException ex) {
196  logger.log(Level.WARNING, "Error translating text for file " + this.contentDescriptor, ex);
197  return TranslateResult.error(Bundle.TranslatedContentViewer_translationException(ex.getMessage()));
198  }
199  }
200 
201 
202  @Override
203  public void done() {
204  try {
205  TranslateResult executionResult = get();
206  if (this.isCancelled()) {
207  throw new InterruptedException();
208  }
209 
210  if (executionResult.isSuccessful()) {
211  String result = executionResult.getResult();
212  int len = result.length();
213  int maxOrientChars = Math.min(len, 1024);
214  String orientDetectSubstring = result.substring(0, maxOrientChars);
215  ComponentOrientation orientation = TextUtil.getTextDirection(orientDetectSubstring);
216  onTextDisplay(result, orientation, Font.PLAIN);
217  } else {
218  onErrorDisplay(executionResult.getErrorMessage(), ComponentOrientation.LEFT_TO_RIGHT, Font.ITALIC);
219  }
220  } catch (InterruptedException | CancellationException ignored) {
221  // Task cancelled, no error.
222  } catch (ExecutionException ex) {
223  logger.log(Level.WARNING, "Error occurred during background task execution for file " + this.contentDescriptor, ex);
224  onErrorDisplay(Bundle.TranslatedContentViewer_translationException(ex.getMessage()), ComponentOrientation.LEFT_TO_RIGHT, Font.ITALIC);
225  }
226  }
227 
235  @NbBundle.Messages({
236  "TranslatedContentViewer.emptyTranslation=The machine translation software did not return any text."
237  })
238  protected String translate(String input) throws NoServiceProviderException, TranslationException {
240  return translatorInstance.translate(input);
241  }
242 }
abstract void onTextDisplay(String text, ComponentOrientation orientation, int font)
TranslateResult(String result, String errorMessage, boolean successful)
TranslateTextTask(boolean translateText, String fileDescriptor)
void onErrorDisplay(String text, ComponentOrientation orientation, int font)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
static ComponentOrientation getTextDirection(String text)
Definition: TextUtil.java:36
void onProgressDisplay(String text, ComponentOrientation orientation, int font)

Copyright © 2012-2022 Basis Technology. Generated on: Tue Aug 1 2023
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.