19package org.sleuthkit.autopsy.contentviewers;
21import java.awt.BorderLayout;
22import java.awt.Component;
23import java.awt.Container;
24import java.io.IOException;
25import java.lang.reflect.InvocationTargetException;
26import java.util.Arrays;
28import java.util.Properties;
29import java.util.ResourceBundle;
30import java.util.concurrent.ExecutionException;
31import java.util.logging.Level;
33import javax.swing.JPanel;
34import javax.swing.SwingUtilities;
35import javax.swing.SwingWorker;
36import org.icepdf.core.SecurityCallback;
38import org.openide.util.NbBundle;
40import org.sleuthkit.datamodel.AbstractFile;
41import org.sleuthkit.datamodel.ReadContentInputStream;
43import org.sleuthkit.autopsy.coreutils.Logger;
44import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
46import org.icepdf.core.exceptions.PDFException;
47import org.icepdf.core.exceptions.PDFSecurityException;
48import org.icepdf.core.pobjects.Document;
50import org.icepdf.ri.common.ComponentKeyBinding;
51import org.icepdf.ri.common.MyGUISecurityCallback;
52import org.icepdf.ri.common.SwingController;
53import org.icepdf.ri.common.SwingViewBuilder;
54import org.icepdf.ri.common.views.DocumentViewControllerImpl;
55import org.icepdf.ri.common.views.DocumentViewModelImpl;
56import org.icepdf.ri.util.PropertiesManager;
63 private static final Logger logger = Logger.getLogger(PDFViewer.class.getName());
65 private JPanel container;
66 private final PropertiesManager propsManager;
67 private final ResourceBundle messagesBundle;
70 container = createNewContainer();
71 messagesBundle = getMessagesBundle();
72 propsManager = getCustomProperties();
77 return Arrays.asList(
"application/pdf");
81 public void setFile(AbstractFile file) {
83 SwingController controller =
new SwingController(messagesBundle);
86 SwingViewBuilder viewBuilder =
new SwingViewBuilder(controller, propsManager);
89 JPanel icePdfPanel = viewBuilder.buildViewerPanel();
94 ComponentKeyBinding.install(controller, icePdfPanel);
97 icePdfPanel.setPreferredSize(this.container.getPreferredSize());
100 this.container.add(icePdfPanel, BorderLayout.CENTER);
103 enableComponents(container,
false);
107 new SwingWorker<Document, Void>() {
109 protected Document doInBackground() throws PDFException, PDFSecurityException, IOException {
110 ReadContentInputStream stream =
new ReadContentInputStream(file);
111 Document doc =
new Document();
115 doc.setSecurityCallback(createPasswordDialogCallback());
119 doc.setInputStream(stream,
null);
124 protected void done() {
128 Document doc =
get();
129 controller.openDocument(doc, file.getName());
132 controller.setPageViewMode(DocumentViewControllerImpl.ONE_COLUMN_VIEW,
true);
134 controller.setDisplayTool(DocumentViewModelImpl.DISPLAY_TOOL_TEXT_SELECTION);
135 enableComponents(container,
true);
136 }
catch (InterruptedException ex) {
138 }
catch (ExecutionException ex) {
139 Throwable exCause = ex.getCause();
140 if (exCause instanceof PDFSecurityException) {
141 showEncryptionDialog();
143 logger.log(Level.WARNING, String.format(
"PDF content viewer "
144 +
"was unable to open document with id %d and name %s",
145 file.getId(), file.getName()), ex);
148 }
catch (Throwable ex) {
149 logger.log(Level.WARNING, String.format(
"PDF content viewer "
150 +
"was unable to open document with id %d and name %s",
151 file.getId(), file.getName()), ex);
161 private void enableComponents(Container container,
boolean enabled) {
162 Component[] components = container.getComponents();
163 for(Component component : components) {
164 component.setEnabled(enabled);
165 if (component instanceof Container) {
166 enableComponents((Container)component, enabled);
178 container = createNewContainer();
183 private JPanel createNewContainer() {
184 return new JPanel(
new BorderLayout());
188 public boolean isSupported(AbstractFile file) {
196 private PropertiesManager getCustomProperties() {
197 Properties props =
new Properties();
200 props.setProperty(PropertiesManager.PROPERTY_SHOW_UTILITY_SAVE,
"false");
201 props.setProperty(PropertiesManager.PROPERTY_SHOW_UTILITY_OPEN,
"false");
202 props.setProperty(PropertiesManager.PROPERTY_SHOW_UTILITY_PRINT,
"false");
203 props.setProperty(PropertiesManager.PROPERTY_SHOW_TOOLBAR_ANNOTATION,
"false");
204 props.setProperty(PropertiesManager.PROPERTY_SHOW_UTILITYPANE_ANNOTATION,
"false");
208 props.setProperty(
"application.showLocalStorageDialogs",
"false");
210 return new PropertiesManager(System.getProperties(), props, messagesBundle);
213 private ResourceBundle getMessagesBundle() {
214 return NbBundle.getBundle(PDFViewer.class);
218 "PDFViewer.errorDialog=An error occurred while opening this PDF document. "
219 +
"Check the logs for more information. You may continue to use "
220 +
"this feature on other PDF documents."
222 private void showErrorDialog() {
223 MessageNotifyUtil.Message.error(Bundle.PDFViewer_errorDialog());
227 "PDFViewer.encryptedDialog=This document is password protected."
229 private void showEncryptionDialog() {
230 MessageNotifyUtil.Message.error(Bundle.PDFViewer_encryptedDialog());
236 private SecurityCallback createPasswordDialogCallback() {
238 return new MyGUISecurityCallback(
null, messagesBundle) {
239 private String password;
242 public String requestPassword(Document document) {
244 SwingUtilities.invokeAndWait(() -> {
246 this.password = super.requestPassword(document);
248 return this.password;
249 }
catch (InterruptedException | InvocationTargetException ex) {
List< String > getSupportedMIMETypes()