pdfbox-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jahew...@apache.org
Subject svn commit: r1687595 - in /pdfbox/trunk: LICENSE.txt NOTICE.txt tools/src/main/java/org/apache/pdfbox/tools/PDFDebugger.java tools/src/main/java/org/apache/pdfbox/tools/gui/OSXAdapter.java
Date Thu, 25 Jun 2015 18:06:30 GMT
Author: jahewson
Date: Thu Jun 25 18:06:30 2015
New Revision: 1687595

URL: http://svn.apache.org/r1687595
Log:
PDFBOX-2530: Use Apple's cross-platform Java code

Added:
    pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/gui/OSXAdapter.java   (with props)
Modified:
    pdfbox/trunk/LICENSE.txt
    pdfbox/trunk/NOTICE.txt
    pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/PDFDebugger.java

Modified: pdfbox/trunk/LICENSE.txt
URL: http://svn.apache.org/viewvc/pdfbox/trunk/LICENSE.txt?rev=1687595&r1=1687594&r2=1687595&view=diff
==============================================================================
--- pdfbox/trunk/LICENSE.txt (original)
+++ pdfbox/trunk/LICENSE.txt Thu Jun 25 18:06:30 2015
@@ -299,3 +299,46 @@ PaDaF PDF/A preflight (http://sourceforg
   See the License for the specific language governing permissions and
   limitations under the License.
 
+OSXAdapter
+
+  Version: 2.0
+  
+  Disclaimer: IMPORTANT:  This Apple software is supplied to you by 
+  Apple Inc. ("Apple") in consideration of your agreement to the
+  following terms, and your use, installation, modification or
+  redistribution of this Apple software constitutes acceptance of these
+  terms.  If you do not agree with these terms, please do not use,
+  install, modify or redistribute this Apple software.
+  
+  In consideration of your agreement to abide by the following terms, and
+  subject to these terms, Apple grants you a personal, non-exclusive
+  license, under Apple's copyrights in this original Apple software (the
+  "Apple Software"), to use, reproduce, modify and redistribute the Apple
+  Software, with or without modifications, in source and/or binary forms;
+  provided that if you redistribute the Apple Software in its entirety and
+  without modifications, you must retain this notice and the following
+  text and disclaimers in all such redistributions of the Apple Software. 
+  Neither the name, trademarks, service marks or logos of Apple Inc. 
+  may be used to endorse or promote products derived from the Apple
+  Software without specific prior written permission from Apple.  Except
+  as expressly stated in this notice, no other rights or licenses, express
+  or implied, are granted by Apple herein, including but not limited to
+  any patent rights that may be infringed by your derivative works or by
+  other works in which the Apple Software may be incorporated.
+  
+  The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
+  MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+  THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+  FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+  OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+  
+  IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+  MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+  AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+  STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE.
+  
+  Copyright (C) 2003-2007 Apple, Inc., All Rights Reserved

Modified: pdfbox/trunk/NOTICE.txt
URL: http://svn.apache.org/viewvc/pdfbox/trunk/NOTICE.txt?rev=1687595&r1=1687594&r2=1687595&view=diff
==============================================================================
--- pdfbox/trunk/NOTICE.txt (original)
+++ pdfbox/trunk/NOTICE.txt Thu Jun 25 18:06:30 2015
@@ -17,3 +17,6 @@ Copyright 1997, 1998, 2002, 2007, 2010 A
 
 Includes the Zapf Dingbats Glyph List
 Copyright 2002, 2010 Adobe Systems Incorporated.
+
+Includes OSXAdapter
+Copyright (C) 2003-2007 Apple, Inc., All Rights Reserved

Modified: pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/PDFDebugger.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/PDFDebugger.java?rev=1687595&r1=1687594&r2=1687595&view=diff
==============================================================================
--- pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/PDFDebugger.java (original)
+++ pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/PDFDebugger.java Thu Jun 25 18:06:30
2015
@@ -16,9 +16,6 @@
  */
 package org.apache.pdfbox.tools;
 
-//import com.apple.eawt.AppEvent;
-//import com.apple.eawt.Application;
-//import com.apple.eawt.OpenFilesHandler;
 import java.awt.BorderLayout;
 import java.awt.Dimension;
 import java.awt.FileDialog;
@@ -35,6 +32,7 @@ import java.io.File;
 import java.io.FilenameFilter;
 import java.io.IOException;
 import java.io.InputStream;
+import java.lang.reflect.Method;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
@@ -70,6 +68,7 @@ import org.apache.pdfbox.pdmodel.PDDocum
 import org.apache.pdfbox.tools.gui.ArrayEntry;
 import org.apache.pdfbox.tools.gui.DocumentEntry;
 import org.apache.pdfbox.tools.gui.MapEntry;
+import org.apache.pdfbox.tools.gui.OSXAdapter;
 import org.apache.pdfbox.tools.gui.PDFTreeCellRenderer;
 import org.apache.pdfbox.tools.gui.PDFTreeModel;
 import org.apache.pdfbox.tools.gui.PageEntry;
@@ -340,24 +339,49 @@ public class PDFDebugger extends javax.s
             }
         });
         
-        // Mac OS X file open handler
-//        Application.getApplication().setOpenFileHandler(new OpenFilesHandler()
-//        {
-//            @Override
-//            public void openFiles(AppEvent.OpenFilesEvent openFilesEvent)
-//            {
-//                try
-//                {
-//                    readPDFFile(openFilesEvent.getFiles().get(0), "");
-//                }
-//                catch (IOException e)
-//                {
-//                    throw new RuntimeException(e);
-//                }
-//            }
-//        });
+        // Mac OS X file open/quit handler
+        if (IS_MAC_OS)
+        {
+            try
+            {
+                Method osxOpenFiles = getClass().getDeclaredMethod("osxOpenFiles", String.class);
+                osxOpenFiles.setAccessible(true);
+                OSXAdapter.setFileHandler(this, osxOpenFiles);
+
+                Method osxQuit = getClass().getDeclaredMethod("osxQuit");
+                osxQuit.setAccessible(true);
+                OSXAdapter.setQuitHandler(this, osxQuit);
+            }
+            catch (NoSuchMethodException e)
+            {
+                throw new RuntimeException(e);
+            }
+        }
     }//GEN-END:initComponents
 
+    /**
+     * This method is called via reflection on Mac OS X.
+     */
+    private void osxOpenFiles(String filename)
+    {
+        try
+        {
+            readPDFFile(filename, "");
+        }
+        catch (IOException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * This method is called via reflection on Mac OS X.
+     */
+    private void osxQuit()
+    {
+        exitMenuItemActionPerformed(null);
+    }
+    
     private void openMenuItemActionPerformed(ActionEvent evt)
     {
         try
@@ -681,8 +705,6 @@ public class PDFDebugger extends javax.s
     {
         UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
         System.setProperty("apple.laf.useScreenMenuBar", "true");
-        
-        final PDFDebugger viewer = new PDFDebugger();
 
         // handle uncaught exceptions
         Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler()
@@ -697,11 +719,15 @@ public class PDFDebugger extends javax.s
                     sb.append('\n');
                     sb.append(element);
                 }
-                JOptionPane.showMessageDialog(viewer, "Error: " + sb.toString(),"Error",
-                                              JOptionPane.ERROR_MESSAGE);
+                JOptionPane.showMessageDialog(null, "Error: " + sb.toString(),"Error",
+                        JOptionPane.ERROR_MESSAGE);
             }
         });
         
+        final PDFDebugger viewer = new PDFDebugger();
+
+        
+        
         // open file, if any
         String filename = null;
         String password = "";

Added: pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/gui/OSXAdapter.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/gui/OSXAdapter.java?rev=1687595&view=auto
==============================================================================
--- pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/gui/OSXAdapter.java (added)
+++ pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/gui/OSXAdapter.java Thu Jun 25
18:06:30 2015
@@ -0,0 +1,225 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ */
+
+/* 
+ * This file includes code under the following terms:
+ * 			
+ *  Version: 2.0
+ *  
+ *  Disclaimer: IMPORTANT:  This Apple software is supplied to you by 
+ *  Apple Inc. ("Apple") in consideration of your agreement to the
+ *  following terms, and your use, installation, modification or
+ *  redistribution of this Apple software constitutes acceptance of these
+ *  terms.  If you do not agree with these terms, please do not use,
+ *  install, modify or redistribute this Apple software.
+ *  
+ *  In consideration of your agreement to abide by the following terms, and
+ *  subject to these terms, Apple grants you a personal, non-exclusive
+ *  license, under Apple's copyrights in this original Apple software (the
+ *  "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ *  Software, with or without modifications, in source and/or binary forms;
+ *  provided that if you redistribute the Apple Software in its entirety and
+ *  without modifications, you must retain this notice and the following
+ *  text and disclaimers in all such redistributions of the Apple Software. 
+ *  Neither the name, trademarks, service marks or logos of Apple Inc. 
+ *  may be used to endorse or promote products derived from the Apple
+ *  Software without specific prior written permission from Apple.  Except
+ *  as expressly stated in this notice, no other rights or licenses, express
+ *  or implied, are granted by Apple herein, including but not limited to
+ *  any patent rights that may be infringed by your derivative works or by
+ *  other works in which the Apple Software may be incorporated.
+ *  
+ *  The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
+ *  MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ *  THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ *  FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ *  OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+ *  
+ *  IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ *  INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ *  MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ *  AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ *  STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ *  POSSIBILITY OF SUCH DAMAGE.
+ *  
+ *  Copyright (C) 2003-2007 Apple, Inc., All Rights Reserved
+ */
+
+package org.apache.pdfbox.tools.gui;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+/**
+ * Hooks existing preferences/about/quit functionality from an
+ * existing Java app into handlers for the Mac OS X application menu.
+ * Uses a Proxy object to dynamically implement the 
+ * com.apple.eawt.ApplicationListener interface and register it with the
+ * com.apple.eawt.Application object.  This allows the complete project
+ * to be both built and run on any platform without any stubs or 
+ * placeholders. Useful for developers looking to implement Mac OS X 
+ * features while supporting multiple platforms with minimal impact.
+ */
+public class OSXAdapter implements InvocationHandler
+{
+
+    protected Object targetObject;
+    protected Method targetMethod;
+    protected String proxySignature;
+
+    static Object macOSXApplication;
+
+    // Pass this method an Object and Method equipped to perform application shutdown logic
+    // The method passed should return a boolean stating whether or not the quit should occur
+    public static void setQuitHandler(Object target, Method quitHandler) {
+        setHandler(new OSXAdapter("handleQuit", target, quitHandler));
+    }
+
+    // Pass this method an Object and Method equipped to display application info
+    // They will be called when the About menu item is selected from the application menu
+    public static void setAboutHandler(Object target, Method aboutHandler) {
+        boolean enableAboutMenu = (target != null && aboutHandler != null);
+        if (enableAboutMenu) {
+            setHandler(new OSXAdapter("handleAbout", target, aboutHandler));
+        }
+        // If we're setting a handler, enable the About menu item by calling
+        // com.apple.eawt.Application reflectively
+        try {
+            Method enableAboutMethod = macOSXApplication.getClass().getDeclaredMethod("setEnabledAboutMenu",
new Class[] { boolean.class });
+            enableAboutMethod.invoke(macOSXApplication, new Object[] { Boolean.valueOf(enableAboutMenu)
});
+        } catch (Exception ex) {
+            System.err.println("OSXAdapter could not access the About Menu");
+            throw new RuntimeException(ex);
+        }
+    }
+
+    // Pass this method an Object and a Method equipped to display application options
+    // They will be called when the Preferences menu item is selected from the application
menu
+    public static void setPreferencesHandler(Object target, Method prefsHandler) {
+        boolean enablePrefsMenu = (target != null && prefsHandler != null);
+        if (enablePrefsMenu) {
+            setHandler(new OSXAdapter("handlePreferences", target, prefsHandler));
+        }
+        // If we're setting a handler, enable the Preferences menu item by calling
+        // com.apple.eawt.Application reflectively
+        try {
+            Method enablePrefsMethod = macOSXApplication.getClass().getDeclaredMethod("setEnabledPreferencesMenu",
new Class[] { boolean.class });
+            enablePrefsMethod.invoke(macOSXApplication, new Object[] { Boolean.valueOf(enablePrefsMenu)
});
+        } catch (Exception ex) {
+            System.err.println("OSXAdapter could not access the About Menu");
+            throw new RuntimeException(ex);
+        }
+    }
+
+    // Pass this method an Object and a Method equipped to handle document events from the
Finder
+    // Documents are registered with the Finder via the CFBundleDocumentTypes dictionary
in the 
+    // application bundle's Info.plist
+    public static void setFileHandler(Object target, Method fileHandler) {
+        setHandler(new OSXAdapter("handleOpenFile", target, fileHandler) {
+            // Override OSXAdapter.callTarget to send information on the
+            // file to be opened
+            public boolean callTarget(Object appleEvent) {
+                if (appleEvent != null) {
+                    try {
+                        Method getFilenameMethod = appleEvent.getClass().getDeclaredMethod("getFilename",
(Class[])null);
+                        String filename = (String) getFilenameMethod.invoke(appleEvent, (Object[])null);
+                        this.targetMethod.invoke(this.targetObject, new Object[] { filename
});
+                    } catch (Exception ex) {
+                        throw new RuntimeException(ex);
+                    }
+                }
+                return true;
+            }
+        });
+    }
+
+    // setHandler creates a Proxy object from the passed OSXAdapter and adds it as an ApplicationListener
+    public static void setHandler(OSXAdapter adapter) {
+        try {
+            Class<?> applicationClass = Class.forName("com.apple.eawt.Application");
+            if (macOSXApplication == null) {
+                macOSXApplication = applicationClass.getConstructor((Class[])null).newInstance((Object[])null);
+            }
+            Class<?> applicationListenerClass = Class.forName("com.apple.eawt.ApplicationListener");
+            Method addListenerMethod = applicationClass.getDeclaredMethod("addApplicationListener",
new Class[] { applicationListenerClass });
+            // Create a proxy object around this handler that can be reflectively added as
an Apple ApplicationListener
+            Object osxAdapterProxy = Proxy.newProxyInstance(OSXAdapter.class.getClassLoader(),
new Class[]{applicationListenerClass}, adapter);
+            addListenerMethod.invoke(macOSXApplication, new Object[] { osxAdapterProxy });
+        } catch (ClassNotFoundException cnfe) {
+            System.err.println("This version of Mac OS X does not support the Apple EAWT.
 ApplicationEvent handling has been disabled (" + cnfe + ")");
+        } catch (Exception ex) {  // Likely a NoSuchMethodException or an IllegalAccessException
loading/invoking eawt.Application methods
+            System.err.println("Mac OS X Adapter could not talk to EAWT:");
+            throw new RuntimeException(ex);
+        }
+    }
+
+    // Each OSXAdapter has the name of the EAWT method it intends to listen for (handleAbout,
for example),
+    // the Object that will ultimately perform the task, and the Method to be called on that
Object
+    protected OSXAdapter(String proxySignature, Object target, Method handler) {
+        this.proxySignature = proxySignature;
+        this.targetObject = target;
+        this.targetMethod = handler;
+    }
+
+    // Override this method to perform any operations on the event 
+    // that comes with the various callbacks
+    // See setFileHandler above for an example
+    public boolean callTarget(Object appleEvent) throws InvocationTargetException, IllegalAccessException
{
+        Object result = targetMethod.invoke(targetObject, (Object[])null);
+        if (result == null) {
+            return true;
+        }
+        return Boolean.valueOf(result.toString()).booleanValue();
+    }
+
+    // InvocationHandler implementation
+    // This is the entry point for our proxy object; it is called every time an ApplicationListener
method is invoked
+    public Object invoke (Object proxy, Method method, Object[] args) throws Throwable {
+        if (isCorrectMethod(method, args)) {
+            boolean handled = callTarget(args[0]);
+            setApplicationEventHandled(args[0], handled);
+        }
+        // All of the ApplicationListener methods are void; return null regardless of what
happens
+        return null;
+    }
+
+    // Compare the method that was called to the intended method when the OSXAdapter instance
was created
+    // (e.g. handleAbout, handleQuit, handleOpenFile, etc.)
+    protected boolean isCorrectMethod(Method method, Object[] args) {
+        return (targetMethod != null && proxySignature.equals(method.getName()) &&
args.length == 1);
+    }
+
+    // It is important to mark the ApplicationEvent as handled and cancel the default behavior
+    // This method checks for a boolean result from the proxy method and sets the event accordingly
+    protected void setApplicationEventHandled(Object event, boolean handled) {
+        if (event != null) {
+            try {
+                Method setHandledMethod = event.getClass().getDeclaredMethod("setHandled",
new Class[] { boolean.class });
+                // If the target method returns a boolean, use that as a hint
+                setHandledMethod.invoke(event, new Object[] { Boolean.valueOf(handled) });
+            } catch (Exception ex) {
+                System.err.println("OSXAdapter was unable to handle an ApplicationEvent:
" + event);
+                throw new RuntimeException(ex);
+            }
+        }
+    }
+}

Propchange: pdfbox/trunk/tools/src/main/java/org/apache/pdfbox/tools/gui/OSXAdapter.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message