PageRenderTime 30ms CodeModel.GetById 13ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 1ms

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