19 package org.sleuthkit.autopsy.contentviewers;
21 import java.awt.BorderLayout;
22 import java.awt.Component;
23 import java.awt.Container;
24 import java.io.IOException;
25 import java.lang.reflect.InvocationTargetException;
26 import java.util.Arrays;
27 import java.util.List;
28 import java.util.Properties;
29 import java.util.ResourceBundle;
30 import java.util.concurrent.ExecutionException;
31 import java.util.logging.Level;
33 import javax.swing.JPanel;
34 import javax.swing.SwingUtilities;
35 import javax.swing.SwingWorker;
36 import org.icepdf.core.SecurityCallback;
38 import org.openide.util.NbBundle;
46 import org.icepdf.core.exceptions.PDFException;
47 import org.icepdf.core.exceptions.PDFSecurityException;
48 import org.icepdf.core.pobjects.Document;
50 import org.icepdf.ri.common.ComponentKeyBinding;
51 import org.icepdf.ri.common.MyGUISecurityCallback;
52 import org.icepdf.ri.common.SwingController;
53 import org.icepdf.ri.common.SwingViewBuilder;
54 import org.icepdf.ri.common.views.DocumentViewControllerImpl;
55 import org.icepdf.ri.common.views.DocumentViewModelImpl;
56 import org.icepdf.ri.util.PropertiesManager;
61 final class PDFViewer
implements FileTypeViewer {
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();
76 public List<String> getSupportedMIMETypes() {
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);
172 public Component getComponent() {
177 public void resetComponent() {
178 container = createNewContainer();
183 private JPanel createNewContainer() {
184 return new JPanel(
new BorderLayout());
188 public boolean isSupported(AbstractFile file) {
189 return getSupportedMIMETypes().contains(file.getMIMEType());
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) {