19 package org.sleuthkit.autopsy.contentviewers;
 
   21 import java.awt.BorderLayout;
 
   22 import java.awt.Component;
 
   23 import java.io.IOException;
 
   24 import java.lang.reflect.InvocationTargetException;
 
   25 import java.util.Arrays;
 
   26 import java.util.List;
 
   27 import java.util.Properties;
 
   28 import java.util.ResourceBundle;
 
   29 import java.util.concurrent.ExecutionException;
 
   30 import java.util.logging.Level;
 
   32 import javax.swing.JPanel;
 
   33 import javax.swing.SwingUtilities;
 
   34 import javax.swing.SwingWorker;
 
   35 import org.icepdf.core.SecurityCallback;
 
   37 import org.openide.util.NbBundle;
 
   45 import org.icepdf.core.exceptions.PDFException;
 
   46 import org.icepdf.core.exceptions.PDFSecurityException;
 
   47 import org.icepdf.core.pobjects.Document;
 
   49 import org.icepdf.ri.common.ComponentKeyBinding;
 
   50 import org.icepdf.ri.common.MyGUISecurityCallback;
 
   51 import org.icepdf.ri.common.SwingController;
 
   52 import org.icepdf.ri.common.SwingViewBuilder;
 
   53 import org.icepdf.ri.common.views.DocumentViewControllerImpl;
 
   54 import org.icepdf.ri.common.views.DocumentViewModelImpl;
 
   55 import org.icepdf.ri.util.PropertiesManager;
 
   60 final class PDFViewer 
implements FileTypeViewer {
 
   62     private static final Logger logger = Logger.getLogger(PDFViewer.class.getName());
 
   64     private JPanel container;
 
   65     private final PropertiesManager propsManager;
 
   66     private final ResourceBundle messagesBundle;
 
   69         container = createNewContainer();
 
   70         messagesBundle = getMessagesBundle();
 
   71         propsManager = getCustomProperties();
 
   75     public List<String> getSupportedMIMETypes() {
 
   76         return Arrays.asList(
"application/pdf");
 
   80     public void setFile(AbstractFile file) {
 
   82         SwingController controller = 
new SwingController(messagesBundle);
 
   85         SwingViewBuilder viewBuilder = 
new SwingViewBuilder(controller, propsManager);
 
   88         JPanel icePdfPanel = viewBuilder.buildViewerPanel();
 
   93         ComponentKeyBinding.install(controller, icePdfPanel);
 
   96         icePdfPanel.setPreferredSize(this.container.getPreferredSize());
 
   99         this.container.add(icePdfPanel, BorderLayout.CENTER);
 
  103         new SwingWorker<Document, Void>() {
 
  105             protected Document doInBackground() throws PDFException, PDFSecurityException, IOException {
 
  106                 ReadContentInputStream stream = 
new ReadContentInputStream(file);
 
  107                 Document doc = 
new Document();
 
  111                 doc.setSecurityCallback(createPasswordDialogCallback());
 
  115                 doc.setInputStream(stream, null);
 
  120             protected void done() {
 
  124                     Document doc = 
get();
 
  125                     controller.openDocument(doc, null);
 
  128                     controller.setPageViewMode(DocumentViewControllerImpl.ONE_COLUMN_VIEW, 
true);
 
  130                     controller.setDisplayTool(DocumentViewModelImpl.DISPLAY_TOOL_TEXT_SELECTION);
 
  131                 } 
catch (InterruptedException ex) {
 
  133                 } 
catch (ExecutionException ex) {
 
  134                     Throwable exCause = ex.getCause();
 
  135                     if (exCause instanceof PDFSecurityException) {
 
  136                         showEncryptionDialog();
 
  138                         logger.log(Level.WARNING, String.format(
"PDF content viewer " 
  139                                 + 
"was unable to open document with id %d and name %s",
 
  140                                 file.getId(), file.getName()), ex);
 
  149     public Component getComponent() {
 
  154     public void resetComponent() {
 
  155         container = createNewContainer();
 
  160     private JPanel createNewContainer() {
 
  161         return new JPanel(
new BorderLayout());
 
  165     public boolean isSupported(AbstractFile file) {
 
  166         return getSupportedMIMETypes().contains(file.getMIMEType());
 
  173     private PropertiesManager getCustomProperties() {
 
  174         Properties props = 
new Properties();
 
  177         props.setProperty(PropertiesManager.PROPERTY_SHOW_UTILITY_SAVE, 
"false");
 
  178         props.setProperty(PropertiesManager.PROPERTY_SHOW_UTILITY_OPEN, 
"false");
 
  179         props.setProperty(PropertiesManager.PROPERTY_SHOW_UTILITY_PRINT, 
"false");
 
  180         props.setProperty(PropertiesManager.PROPERTY_SHOW_TOOLBAR_ANNOTATION, 
"false");
 
  181         props.setProperty(PropertiesManager.PROPERTY_SHOW_UTILITYPANE_ANNOTATION, 
"false");
 
  185         props.setProperty(
"application.showLocalStorageDialogs", 
"false");
 
  187         return new PropertiesManager(System.getProperties(), props, messagesBundle);
 
  190     private ResourceBundle getMessagesBundle() {
 
  191         return NbBundle.getBundle(PDFViewer.class);
 
  195         "PDFViewer.errorDialog=An error occurred while opening this PDF document. " 
  196         + 
"Check the logs for more information. You may continue to use " 
  197         + 
"this feature on other PDF documents." 
  199     private void showErrorDialog() {
 
  200         MessageNotifyUtil.Message.error(Bundle.PDFViewer_errorDialog());
 
  204         "PDFViewer.encryptedDialog=This document is password protected." 
  206     private void showEncryptionDialog() {
 
  207         MessageNotifyUtil.Message.error(Bundle.PDFViewer_encryptedDialog());
 
  213     private SecurityCallback createPasswordDialogCallback() {
 
  215         return new MyGUISecurityCallback(null, messagesBundle) {
 
  216             private String password;
 
  219             public String requestPassword(Document document) {
 
  221                     SwingUtilities.invokeAndWait(() -> {
 
  223                         this.password = super.requestPassword(document);
 
  225                     return this.password;
 
  226                 } 
catch (InterruptedException | InvocationTargetException ex) {