package com.limegroup.gnutella.util;
import java.util.Enumeration;
import com.apple.cocoa.foundation.NSMutableArray;
import com.apple.cocoa.foundation.NSMutableDictionary;
import com.apple.cocoa.foundation.NSObject;
import com.apple.cocoa.foundation.NSUserDefaults;
import com.apple.cocoa.foundation.NSSystem;
/**
* A collection of utility methods for OSX.
* These methods should only be called if run from OSX,
* otherwise ClassNotFoundErrors may occur.
*
* To determine if the Cocoa Foundation classes are present,
* use the method CommonUtils.isCocoaFoundationAvailable().
*/
public class MacOSXUtils {
private MacOSXUtils() {}
/**
* The login domain.
*/
private static final String LOGIN_DOMAIN = "loginwindow";
/**
* The name of the dictionary which contains the apps that are launched.
*/
private static final String DICTIONARY =
"AutoLaunchedApplicationDictionary";
/**
* The key for "hide"
*/
private static final String HIDE = "Hide";
/**
* The key for "path";
*/
private static final String PATH = "Path";
/**
* The name of the app that launches.
*/
private static final String APP_NAME = "LimeWire At Login.app";
/**
* Creates a mutable clone of the specified object.
*/
private static Object createMutableClone(Object a)
throws CloneNotSupportedException {
if(a == null)
throw new CloneNotSupportedException();
else if (!(a instanceof NSObject))
throw new CloneNotSupportedException();
else
return ((NSObject)a).mutableClone();
}
/**
* Modifies the loginwindow.plist file to either include or exclude
* starting up LimeWire.
*/
public static void setLoginStatus(boolean allow) {
Object temp; // Used for the assignment when retrieiving as an object.
NSUserDefaults defaults = NSUserDefaults.standardUserDefaults();
temp = defaults.persistentDomainForName(LOGIN_DOMAIN);
// If no domain existed, create one and make its initial dictionary.
if(temp == null) {
temp = new NSMutableDictionary();
((NSMutableDictionary)temp).setObjectForKey(new NSMutableArray(),
DICTIONARY);
} else if(!(temp instanceof NSMutableDictionary))
return; // nothing we can do.
NSMutableDictionary logins = null;
try {
logins = (NSMutableDictionary)createMutableClone(temp);
} catch(CloneNotSupportedException cnso) {
//nothing we can do, exit.
return;
}
// Retrieve the array that contains the various dictionaries
temp = logins.objectForKey(DICTIONARY);
// If no object existed, create one.
if(temp == null)
temp = new NSMutableArray();
// if it is not an NSMutableArray, exit (we dunno how to recover)
else if(!(temp instanceof NSMutableArray))
return;
NSMutableArray allApps = null;
try {
allApps = (NSMutableArray)createMutableClone(temp);
} catch(CloneNotSupportedException cnso) {
// nothing we can do, exit.
return;
}
Enumeration items = allApps.objectEnumerator();
boolean found = false;
// Iterate through each item in the array,
// looking for one whose 'Path' key has a value
// containing the stub startup app LimeWire uses.
while(items.hasMoreElements()) {
temp = items.nextElement();
// If it isn't an NSMutableDictionary, ignore it
// because we won't know how to handle it.
if(!(temp instanceof NSMutableDictionary))
continue;
NSMutableDictionary itemInfo = null;
try {
itemInfo = (NSMutableDictionary)createMutableClone(temp);
} catch(CloneNotSupportedException cnse) {
continue; // can't do anything, continue.
}
Object path = itemInfo.objectForKey(PATH);
// If it isn't a String, ignore it because we
// won't know how to handle it.
if(!(path instanceof String))
continue;
String itemPath = (String)path;
if(itemPath.indexOf(APP_NAME) != -1) {
found = true;
// If not allowed, remove.
// We must remove with temp, not itemInfo, because itemInfo
// is a clone.
if(!allow)
allApps.removeIdenticalObject(temp);
else
itemInfo.setObjectForKey(getAppDir(), PATH);
break;
}
}
if(!found) {
if(!allow)
return;
else {
NSMutableDictionary newItem = new NSMutableDictionary();
newItem.setObjectForKey(new Integer(0), HIDE);
newItem.setObjectForKey(getAppDir(), PATH);
allApps.addObject(newItem);
}
}
//Make sure we set add our new allApps to the dictionary.
logins.setObjectForKey(allApps, DICTIONARY);
// Set the new domain.
defaults.setPersistentDomainForName(logins, LOGIN_DOMAIN);
// Synchronize it to disk immediately
defaults.synchronize();
}
/**
* Gets the full user's name.
*/
public static String getUserName() {
return NSSystem.currentFullUserName();
}
/**
* Retrieves the app directory & name.
* If the user is not running from the bundled app as we named it,
* defaults to /Applications/LimeWire/ as the directory of the app.
*/
private static String getAppDir() {
String appDir = "/Applications/LimeWire/";
String path = CommonUtils.getCurrentDirectory().getPath();
int app = path.indexOf("LimeWire.app");
if(app != -1)
appDir = path.substring(0, app);
return appDir + APP_NAME;
}
}