Autopsy 4.22.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
TranslatablePanel.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 */
19package org.sleuthkit.autopsy.contentviewers;
20
21import com.google.common.util.concurrent.ThreadFactoryBuilder;
22import java.awt.Component;
23import java.awt.ComponentOrientation;
24import java.io.IOException;
25import java.util.concurrent.ExecutorService;
26import java.util.concurrent.Executors;
27import java.util.concurrent.ThreadFactory;
28import javax.swing.ImageIcon;
29import javax.swing.JPanel;
30import javax.swing.SwingUtilities;
31import org.openide.util.NbBundle.Messages;
32import org.sleuthkit.autopsy.texttranslation.NoServiceProviderException;
33import org.sleuthkit.autopsy.texttranslation.TextTranslationService;
34import org.sleuthkit.autopsy.texttranslation.TranslationException;
35import org.sleuthkit.autopsy.texttranslation.ui.TranslateTextTask;
36
40public class TranslatablePanel extends JPanel {
41
47 public class TranslatablePanelException extends Exception {
48 public static final long serialVersionUID = 1L;
49
50 TranslatablePanelException(String message) {
51 super(message);
52 }
53
54 TranslatablePanelException(String message, Throwable cause) {
55 super(message, cause);
56 }
57 }
58
59
64 public interface ContentComponent {
69 Component getRootComponent();
70
77 void setContent(String content, ComponentOrientation orientation) throws TranslatablePanelException;
78 }
79
80
84 private static class TranslateOption {
85
86 private final String text;
87 private final boolean translate;
88
89 TranslateOption(String text, boolean translate) {
90 this.text = text;
91 this.translate = translate;
92 }
93
94 String getText() {
95 return text;
96 }
97
98 @Override
99 public String toString() {
100 return text;
101 }
102
103 boolean shouldTranslate() {
104 return translate;
105 }
106 }
107
111 private static class TranslatedText {
112
113 private final String text;
114 private final ComponentOrientation orientation;
115
116 TranslatedText(String text, ComponentOrientation orientation) {
117 this.text = text;
118 this.orientation = orientation;
119 }
120
121 String getText() {
122 return text;
123 }
124
125 ComponentOrientation getOrientation() {
126 return orientation;
127 }
128 }
129
134 private class OnTranslation extends TranslateTextTask {
135
136 OnTranslation() {
137 super(true, contentDescriptor == null ? "" : contentDescriptor);
138 }
139
140 @Override
141 protected String translate(String input) throws NoServiceProviderException, TranslationException {
142 // This defers to the outer class method so that it can be overridden for items like html, rtf, etc.
143 return retrieveTranslation(input);
144 }
145
146 @Override
147 protected void onProgressDisplay(String text, ComponentOrientation orientation, int font) {
148 setStatus(text, false);
149 }
150
151 @Override
152 protected void onErrorDisplay(String text, ComponentOrientation orientation, int font) {
153 setStatus(text, true);
154 }
155
156 @Override
157 protected String retrieveText() throws IOException, InterruptedException, IllegalStateException {
158 return content == null ? "" : content;
159 }
160
161 @Override
162 protected void onTextDisplay(String text, ComponentOrientation orientation, int font) {
163 // On successful acquire, this caches the result and set the text.
164 setCachedTranslated(new TranslatedText(text, orientation));
165 setChildComponentContent(text, orientation);
166
167 // This clears any status that may be present.
168 clearStatus();
169 }
170 }
171
172 private static final long serialVersionUID = 1L;
173 private static final ComponentOrientation DEFAULT_ORIENTATION = ComponentOrientation.LEFT_TO_RIGHT;
174
175 private final ImageIcon warningIcon = new ImageIcon(TranslatablePanel.class.getResource("/org/sleuthkit/autopsy/images/warning16.png"));
176
179 private final ThreadFactory translationThreadFactory = new ThreadFactoryBuilder().setNameFormat("translatable-panel-%d").build();
180 private final ExecutorService executorService = Executors.newSingleThreadExecutor(translationThreadFactory);
181
182 private final Object cachedTranslatedLock = new Object();
183 private final Object backgroundTaskLock = new Object();
184
185 private String content;
186 private String contentDescriptor;
187 private boolean prevTranslateSelection;
188
190 private volatile OnTranslation backgroundTask = null;
191
192 @Messages({"TranslatablePanel.comboBoxOption.originalText=Original Text",
193 "TranslatablePanel.comboBoxOption.translatedText=Translated Text"})
195 this(
197 Bundle.TranslatablePanel_comboBoxOption_originalText(),
198 Bundle.TranslatablePanel_comboBoxOption_translatedText(),
199 null,
201 }
202
206 TranslatablePanel(ContentComponent contentComponent, String origOptionText, String translatedOptionText, String origContent,
208 this.contentComponent = contentComponent;
209 this.translationService = translationService;
210
212 additionalInit(contentComponent.getRootComponent(), origOptionText, translatedOptionText);
213 reset();
214 }
215
216
217
222 synchronized (cachedTranslatedLock) {
223 return cachedTranslated;
224 }
225 }
226
230 private void setCachedTranslated(TranslatedText translated) {
231 synchronized (cachedTranslatedLock) {
232 this.cachedTranslated = translated;
233 }
234 }
235
240 synchronized (backgroundTaskLock) {
241 if (backgroundTask != null && !backgroundTask.isDone()) {
242 backgroundTask.cancel(true);
243 }
244 backgroundTask = null;
245 }
246 }
247
251 private void runTranslationTask() {
252 synchronized (backgroundTaskLock) {
255
256 //Pass the background task to a single threaded pool to keep
257 //the number of jobs running to one.
259 }
260 }
261
266 public final void reset() {
267 setContent(null, null);
268 }
269
275 public void setContent(String content, String contentDescriptor) {
278 this.translateComboBox.setSelectedIndex(0);
279 this.prevTranslateSelection = false;
280 this.content = content;
281 this.contentDescriptor = contentDescriptor;
282 clearStatus();
285 }
286
297 return translationService.translate(input);
298 }
299
303 private void clearStatus() {
304 setStatus(null, false);
305 }
306
312 private synchronized void setStatus(String msg, boolean showWarningIcon) {
313 statusLabel.setText(msg);
314 statusLabel.setIcon(showWarningIcon ? warningIcon : null);
315 }
316
320 private void setTranslationEnabled() {
321 translateComboBox.setEnabled(this.translationService.hasProvider());
322 }
323
331
337 @Messages({"# {0} - exception message", "TranslatablePanel.onSetContentError.text=There was an error displaying the text: {0}"})
338 private synchronized void setChildComponentContent(String content, ComponentOrientation orientation) {
339 SwingUtilities.invokeLater(() -> {
340 try {
341 contentComponent.setContent(content, orientation);
342 } catch (TranslatablePanelException ex) {
343 setStatus(Bundle.TranslatablePanel_onSetContentError_text(ex.getMessage()), true);
344 }
345 });
346 }
347
351 private void additionalInit(Component rootComponent, String origOptionText, String translatedOptionText) {
352 add(rootComponent, java.awt.BorderLayout.CENTER);
353 translateComboBox.removeAllItems();
354 translateComboBox.addItem(new TranslateOption(origOptionText, false));
355 translateComboBox.addItem(new TranslateOption(translatedOptionText, true));
356 }
357
362 private void handleComboBoxChange(TranslateOption translateOption) {
363 boolean curTranslateSelection = translateOption.shouldTranslate();
364 if (curTranslateSelection != this.prevTranslateSelection) {
365 this.prevTranslateSelection = curTranslateSelection;
366
368 clearStatus();
369
370 if (curTranslateSelection) {
371 TranslatedText translated = getCachedTranslated();
372 if (translated != null) {
373 setChildComponentContent(translated.getText(), translated.getOrientation());
374 } else {
376 }
377 } else {
379 }
380 }
381 }
382
388 @SuppressWarnings("unchecked")
389 // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
390 private void initComponents() {
391
392 translationBar = new javax.swing.JPanel();
393 translateComboBox = new javax.swing.JComboBox<>();
394 statusLabel = new javax.swing.JLabel();
395
396 setMaximumSize(new java.awt.Dimension(2000, 2000));
397 setMinimumSize(new java.awt.Dimension(2, 2));
398 setName(""); // NOI18N
399 setPreferredSize(new java.awt.Dimension(100, 58));
400 setVerifyInputWhenFocusTarget(false);
401 setLayout(new java.awt.BorderLayout());
402
403 translationBar.setBorder(javax.swing.BorderFactory.createEtchedBorder());
404 translationBar.setMaximumSize(new java.awt.Dimension(182, 24));
405 translationBar.setPreferredSize(new java.awt.Dimension(182, 24));
406 translationBar.setLayout(new java.awt.BorderLayout());
407
408 translateComboBox.setMaximumSize(new java.awt.Dimension(200, 20));
409 translateComboBox.setMinimumSize(new java.awt.Dimension(200, 20));
410 translateComboBox.setName(""); // NOI18N
411 translateComboBox.setPreferredSize(new java.awt.Dimension(200, 20));
412 translateComboBox.addActionListener(new java.awt.event.ActionListener() {
413 public void actionPerformed(java.awt.event.ActionEvent evt) {
414 translateComboBoxActionPerformed(evt);
415 }
416 });
417 translationBar.add(translateComboBox, java.awt.BorderLayout.LINE_END);
418
419 statusLabel.setMaximumSize(new java.awt.Dimension(32767, 32767));
420 translationBar.add(statusLabel, java.awt.BorderLayout.CENTER);
421
422 add(translationBar, java.awt.BorderLayout.NORTH);
423 }// </editor-fold>//GEN-END:initComponents
424
425 private void translateComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_translateComboBoxActionPerformed
427 }//GEN-LAST:event_translateComboBoxActionPerformed
428
429 // Variables declaration - do not modify//GEN-BEGIN:variables
430 private javax.swing.JLabel statusLabel;
431 private javax.swing.JComboBox<TranslateOption> translateComboBox;
432 private javax.swing.JPanel translationBar;
433 // End of variables declaration//GEN-END:variables
434}
void onProgressDisplay(String text, ComponentOrientation orientation, int font)
void onErrorDisplay(String text, ComponentOrientation orientation, int font)
void onTextDisplay(String text, ComponentOrientation orientation, int font)
javax.swing.JComboBox< TranslateOption > translateComboBox
void handleComboBoxChange(TranslateOption translateOption)
synchronized void setChildComponentContent(String content, ComponentOrientation orientation)
void translateComboBoxActionPerformed(java.awt.event.ActionEvent evt)
void additionalInit(Component rootComponent, String origOptionText, String translatedOptionText)
void setContent(String content, String contentDescriptor)
synchronized void setStatus(String msg, boolean showWarningIcon)
TranslateTextTask(boolean translateText, String fileDescriptor)
void setContent(String content, ComponentOrientation orientation)

Copyright © 2012-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.