/edu/uncc/parsets/util/osabstraction/MacOSX.java

https://code.google.com/p/parsets/ · Java · 181 lines · 120 code · 15 blank · 46 comment · 11 complexity · 8c4ddcdd8da16585b1f0280b514fa7a3 MD5 · raw file

  1. package edu.uncc.parsets.util.osabstraction;
  2. import java.awt.FileDialog;
  3. import java.awt.Frame;
  4. import java.io.File;
  5. import java.lang.reflect.InvocationHandler;
  6. import java.lang.reflect.Method;
  7. import java.lang.reflect.Proxy;
  8. import edu.uncc.parsets.data.LocalDB;
  9. import edu.uncc.parsets.gui.CombinedFileNameFilter;
  10. import edu.uncc.parsets.util.PSLogging;
  11. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
  12. * Copyright (c) 2009, Robert Kosara, Caroline Ziemkiewicz,
  13. * and others (see Authors.txt for full list)
  14. * All rights reserved.
  15. *
  16. * Redistribution and use in source and binary forms, with or without
  17. * modification, are permitted provided that the following conditions are met:
  18. *
  19. * * Redistributions of source code must retain the above copyright
  20. * notice, this list of conditions and the following disclaimer.
  21. * * Redistributions in binary form must reproduce the above copyright
  22. * notice, this list of conditions and the following disclaimer in the
  23. * documentation and/or other materials provided with the distribution.
  24. * * Neither the name of UNC Charlotte nor the names of its contributors
  25. * may be used to endorse or promote products derived from this software
  26. * without specific prior written permission.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY ITS AUTHORS ''AS IS'' AND ANY
  29. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  30. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31. * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
  32. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  33. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  34. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  35. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  36. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  37. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  39. // http://developer.apple.com/documentation/Java/Conceptual/Java14Development/07-NativePlatformIntegration/NativePlatformIntegration.html
  40. // http://developer.apple.com/technotes/tn2007/tn2196.html
  41. @SuppressWarnings("rawtypes")
  42. public class MacOSX extends AbstractOS {
  43. // based on http://www.velocityreviews.com/forums/t151722-class-loading-on-different-opperating-systems.html
  44. // catches methods for com.apple.eawt.ApplicationListener
  45. // http://developer.apple.com/documentation/Java/Reference/1.4.2/appledoc/api/com/apple/eawt/ApplicationListener.html
  46. private static final class ApplicationAdapter implements InvocationHandler {
  47. @SuppressWarnings("unchecked")
  48. public Object invoke(Object proxy, Method method, Object[] args) {
  49. // System.err.println("Call to "+method.getName());
  50. if (method.getName().equals("handleAbout")) {
  51. // TODO: show About box
  52. }
  53. if (method.getName().equals("handleAbout") || method.getName().equals("handleQuit")) {
  54. try {
  55. Class handlerClass = Class.forName("com.apple.eawt.ApplicationEvent");
  56. Method setHandled = handlerClass.getMethod("setHandled", boolean.class);
  57. setHandled.invoke(args[0], Boolean.TRUE);
  58. } catch (Exception e) {
  59. System.err.println(e);
  60. }
  61. }
  62. return null;
  63. }
  64. }
  65. @SuppressWarnings("unchecked")
  66. public MacOSX() {
  67. // this is only for testing the ugly metal LAF to check the vertical label code
  68. // try {
  69. // UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
  70. // } catch (Exception e) {
  71. // // bite me
  72. // }
  73. System.setProperty("apple.laf.useScreenMenuBar", "true");
  74. try {
  75. Class lc = Class.forName("com.apple.eawt.ApplicationListener");
  76. Object listener = Proxy.newProxyInstance(this.getClass().getClassLoader(),
  77. new Class[] { lc }, new ApplicationAdapter());
  78. Class appc = Class.forName("com.apple.eawt.Application");
  79. Object app = appc.newInstance();
  80. Method m = appc.getMethod("addApplicationListener", lc);
  81. m.invoke(app, listener);
  82. } catch (Exception e) {
  83. PSLogging.logger.warn("Could not register Mac OS X application event handler", e);
  84. }
  85. }
  86. /**
  87. * Installs into "~/Library/Application Support/Parallel Sets".
  88. */
  89. @Override
  90. @SuppressWarnings("unchecked")
  91. protected void installRegular(File dbFile) {
  92. PSLogging.logger.info("Installing new database at "
  93. + dbFile.getAbsolutePath());
  94. try {
  95. Class fileManagerClass = Class.forName("com.apple.eio.FileManager");
  96. Method getPathToAppBundle = fileManagerClass
  97. .getMethod("getPathToApplicationBundle");
  98. String srcPath = ((String) getPathToAppBundle.invoke(null))
  99. + "/Contents/Resources/Java/" + LocalDB.LOCALDBFILENAME;
  100. File parentDir = dbFile.getParentFile();
  101. if (!parentDir.exists())
  102. if (parentDir.mkdir() == false)
  103. PSLogging.logger
  104. .fatal("Could not create parent directory");
  105. PSLogging.logger.info("Source file: " + srcPath);
  106. File localDBFile = new File(srcPath);
  107. copyFileNIO(localDBFile, dbFile);
  108. } catch (Exception e) {
  109. PSLogging.logger.fatal("Could not locate source DB file.", e);
  110. }
  111. }
  112. @Override
  113. public String showDialog(Frame frame, CombinedFileNameFilter fileFilter, int mode) {
  114. FileDialog fd = new FileDialog(frame);
  115. fd.setMode(mode);
  116. if (fileFilter != null)
  117. fd.setFilenameFilter(fileFilter);
  118. fd.setDirectory(getDocsDir());
  119. fd.setVisible(true);
  120. if (fd.getFile() != null) {
  121. if (fileFilter.accept(new File(fd.getDirectory()), fd.getFile()))
  122. return fd.getDirectory() + fd.getFile();
  123. else
  124. return fd.getDirectory() + fd.getFile() + fileFilter.getExtension();
  125. } else
  126. return null;
  127. }
  128. private static final Class fmParamTypes[] = { Short.TYPE, Integer.TYPE };
  129. private static final Class os2iParamTypes[] = { String.class };
  130. // Based on code from
  131. // http://stackoverflow.com/questions/567874/how-do-i-find-the-users-documents-folder-with-java-in-os-x
  132. @Override
  133. public String getLocalDBDir() {
  134. return findFolder("asup");
  135. }
  136. public String getDocsDir() {
  137. return findFolder("docs");
  138. }
  139. @SuppressWarnings("unchecked")
  140. private String findFolder(String type) {
  141. String path = null;
  142. try {
  143. Class fileManagerClass = Class.forName("com.apple.eio.FileManager");
  144. Method oSTypeToInt = fileManagerClass.getMethod("OSTypeToInt",
  145. os2iParamTypes);
  146. Method findFolder = fileManagerClass.getMethod("findFolder",
  147. fmParamTypes);
  148. short kUserDomain = fileManagerClass.getField("kUserDomain")
  149. .getShort(null);
  150. int kDDInt = (Integer) oSTypeToInt.invoke(null, type);
  151. path = (String) findFolder.invoke(null, kUserDomain, kDDInt);
  152. } catch (Exception e) {
  153. PSLogging.logger.fatal("Error determining user folder " + type,
  154. e);
  155. }
  156. return path;
  157. }
  158. @Override
  159. public String shortName() {
  160. return "mac";
  161. }
  162. @Override
  163. public boolean isMacOSX() {
  164. return true;
  165. }
  166. }