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) {