package ch.cyberduck.model;
/*
* Copyright (c) 2009 David Kocher. All rights reserved.
* http://cyberduck.ch/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Bug fixes, suggestions and comments should be sent to:
* dkocher@cyberduck.ch
*/
import ch.cyberduck.core.*;
import ch.cyberduck.core.threading.DefaultMainAction;
//import ch.cyberduck.ui.cocoa.IconCache;
import ch.cyberduck.ProxyController;
//import ch.cyberduck.ui.cocoa.application.NSWorkspace;
//import ch.cyberduck.ui.cocoa.foundation.*;
import org.apache.commons.collections.map.AbstractLinkedMap;
import org.apache.commons.collections.map.LRUMap;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
//import org.rococoa.Rococoa;
//import org.rococoa.cocoa.foundation.NSUInteger;
import java.io.File;
import java.util.*;
/**
* @version $Id$
*/
public class FinderLocal extends Local {
private static Logger log = Logger.getLogger(FinderLocal.class);
public FinderLocal(ch.cyberduck.core.Local parent, String name) {
super(parent, name);
}
public FinderLocal(String parent, String name) {
super(parent, name);
}
public FinderLocal(String path) {
super(path);
}
public FinderLocal(File path) {
super(path);
}
public static void register() {
LocalFactory.addFactory(Factory.NATIVE_PLATFORM, new Factory());
}
private static class Factory extends LocalFactory {
@Override
protected Local create() {
return new FinderLocal(System.getProperty("user.home"));
}
@Override
protected Local create(Local parent, String name) {
return new FinderLocal(parent, name);
}
@Override
protected Local create(String parent, String name) {
return new FinderLocal(parent, name);
}
@Override
protected Local create(String path) {
return new FinderLocal(path);
}
@Override
protected Local create(java.io.File path) {
return new FinderLocal(path);
}
}
// @Override
// public void setPath(String name) {
// final String absolute = stringByExpandingTildeInPath(name);
// if(loadNative()) {
// super.setPath(this.resolveAlias(absolute));
// }
// else {
// super.setPath(absolute);
// }
// }
//
// /**
// * @return Name of the file as displayed in the Finder. E.g. a ':' is replaced with '/'.
// */
// @Override
// public String getDisplayName() {
// return NSFileManager.defaultManager().displayNameAtPath(super.getName());
// }
//
// /**
// * @return Path relative to the home directory denoted with a tilde.
// */
// @Override
// public String getAbbreviatedPath() {
// return stringByAbbreviatingWithTildeInPath(this.getAbsolute());
// }
private static boolean JNI_LOADED = false;
private static boolean loadNative() {
if(!JNI_LOADED) {
JNI_LOADED = Native.load("Local");
}
return JNI_LOADED;
}
private native String resolveAlias(String absolute);
/**
* @return Human readable description of file type
*/
@Override
public String kind() {
if(attributes.isFile()) {
// Native file type mapping
final String kind = kind(this.getExtension());
if(StringUtils.isEmpty(kind)) {
return ch.cyberduck.core.i18n.Locale.localizedString("Unknown");
}
return kind;
}
return super.kind();
}
public static native String kind(String extension);
// @Override
// public Permission getPermission() {
// try {
// NSDictionary fileAttributes = NSFileManager.defaultManager().fileAttributes(
// _impl.getAbsolutePath());
// if(null == fileAttributes) {
// log.error("No such file:" + getAbsolute());
// return null;
// }
// NSObject object = fileAttributes.objectForKey(NSFileManager.NSFilePosixPermissions);
// if(null == object) {
// log.error("No such file:" + getAbsolute());
// return null;
// }
// NSNumber posix = Rococoa.cast(object, NSNumber.class);
// String posixString = Integer.toString(posix.intValue() & 0177777, 8);
// return new Permission(Integer.parseInt(posixString.substring(posixString.length() - 3)));
// }
// catch(NumberFormatException e) {
// log.error(e.getMessage());
// return null;
// }
// }
//
// @Override
// public void writePermissions(final Permission perm, final boolean recursive) {
// new ProxyController().invoke(new DefaultMainAction() {
// public void run() {
// boolean success = NSFileManager.defaultManager().setAttributes_ofItemAtPath_error(
// NSDictionary.dictionaryWithObjectsForKeys(
// NSArray.arrayWithObject(NSNumber.numberWithInt(perm.getOctalNumber())),
// NSArray.arrayWithObject(NSFileManager.NSFilePosixPermissions)),
// _impl.getAbsolutePath(), null);
// if(!success) {
// log.error("File attribute changed failed:" + getAbsolute());
// }
// if(attributes.isDirectory() && recursive) {
// for(AbstractPath child : childs()) {
// child.writePermissions(perm, recursive);
// }
// }
// }
// });
// }
//
// @Override
// public void writeModificationDate(final long millis) {
// new ProxyController().invoke(new DefaultMainAction() {
// public void run() {
// boolean success = NSFileManager.defaultManager().setAttributes_ofItemAtPath_error(
// NSDictionary.dictionaryWithObjectsForKeys(
// NSArray.arrayWithObject(NSDate.dateWithTimeIntervalSince1970(millis / 1000)),
// NSArray.arrayWithObject(NSFileManager.NSFileModificationDate)),
// _impl.getAbsolutePath(), null);
// if(!success) {
// log.error("File attribute changed failed:" + getAbsolute());
// }
// }
// });
// }
//
// @Override
// public long getCreationDate() {
// final NSDictionary fileAttributes = NSFileManager.defaultManager().fileAttributes(_impl.getAbsolutePath());
// // If flag is true and path is a symbolic link, the attributes of the linked-to file are returned;
// // if the link points to a nonexistent file, this method returns null. If flag is false,
// // the attributes of the symbolic link are returned.
// if(null == fileAttributes) {
// log.error("No such file:" + getAbsolute());
// return -1;
// }
// NSObject date = fileAttributes.objectForKey(NSFileManager.NSFileCreationDate);
// if(null == date) {
// // Returns an entry’s value given its key, or null if no value is associated with key.
// log.error("No such file:" + getAbsolute());
// return -1;
// }
// return (long) (Rococoa.cast(date, NSDate.class).timeIntervalSince1970() * 1000);
// }
//
// /**
// * NSWorkspace.RecycleOperation
// */
// @Override
// public void trash() {
// if(this.exists()) {
// final Local file = this;
// new ProxyController().invoke(new DefaultMainAction() {
// public void run() {
// log.debug("Move " + file + " to Trash");
// if(!NSWorkspace.sharedWorkspace().performFileOperation(
// NSWorkspace.RecycleOperation,
// file.getParent().getAbsolute(), "",
// NSArray.arrayWithObject(file.getName()))) {
// log.warn("Failed to move " + file.getAbsolute() + " to Trash");
// }
// }
// });
// }
// }
//
// /**
// * Create a new symbolic link from this
// * path if <code>local.symboliclink.resolve</code is true
// */
// @Override
// public boolean touch() {
// if(!Preferences.instance().getBoolean("local.symboliclink.resolve")) {
// if(StringUtils.isNotEmpty(this.getSymlinkTarget())) {
// return NSFileManager.defaultManager().createSymbolicLinkAtPath_withDestinationPath_error(this.getAbsolute(),
// this.getSymlinkTarget(), null);
// }
// }
// return super.touch();
// }
/**
* @param originUrl The URL of the resource originally hosting the quarantined item, from the user's point of
* view. For web downloads, this property is the URL of the web page on which the user initiated
* the download. For attachments, this property is the URL of the resource to which the quarantined
* item was attached (e.g. the email message, calendar event, etc.). The origin URL may be a file URL
* for local resources, or a custom URL to which the quarantining application will respond when asked
* to open it. The quarantining application should respond by displaying the resource to the user.
* Note: The origin URL should not be set to the data URL, or the quarantining application may start
* downloading the file again if the user choses to view the origin URL while resolving a quarantine
* warning.
* @param dataUrl The URL from which the data for the quarantined item data was
* actaully streamed or downloaded, if available
*/
@Override
public void setQuarantine(final String originUrl, final String dataUrl) {
if(!loadNative()) {
return;
}
if(StringUtils.isEmpty(originUrl)) {
log.warn("No origin url given for quarantine");
return;
}
if(StringUtils.isEmpty(dataUrl)) {
log.warn("No data url given for quarantine");
return;
}
new ProxyController().invoke(new DefaultMainAction() {
public void run() {
setQuarantine(getAbsolute(), originUrl, dataUrl);
}
});
}
/**
* UKXattrMetadataStore
*
* @param path Absolute path reference
* @param originUrl Page that linked to the downloaded file
* @param dataUrl Href where the file was downloaded from
*/
private native void setQuarantine(String path, String originUrl, String dataUrl);
/**
* Set the kMDItemWhereFroms on the file.
*
* @param dataUrl Href where the file was downloaded from
*/
@Override
public void setWhereFrom(final String dataUrl) {
if(!loadNative()) {
return;
}
if(StringUtils.isEmpty(dataUrl)) {
log.warn("No data url given for quarantine");
return;
}
new ProxyController().invoke(new DefaultMainAction() {
public void run() {
setWhereFrom(getAbsolute(), dataUrl);
}
});
}
/**
* Set the kMDItemWhereFroms on the file.
*
* @param path Absolute path reference
* @param dataUrl Href where the file was downloaded from
*/
private native void setWhereFrom(String path, String dataUrl);
// /**
// * Update the custom icon for the file in the Finder
// *
// * @param progress An integer from -1 and 9. If -1 is passed,
// * the resource fork with the custom icon is removed from the file.
// */
// @Override
// public void setIcon(final int progress) {
// if(progress > 9 || progress < -1) {
// log.warn("Local#setIcon:" + progress);
// return;
// }
// if(Preferences.instance().getBoolean("queue.download.updateIcon")) {
// if(!loadNative()) {
// return;
// }
// final String path = this.getAbsolute();
// new ProxyController().invoke(new DefaultMainAction() {
// public void run() {
// if(-1 == progress) {
// NSWorkspace.sharedWorkspace().setIcon_forFile_options(
// null, getAbsolute(), new NSUInteger(0));
// }
// else {
// // Specify 0 if you want to generate icons in all available icon representation formats
// NSWorkspace.sharedWorkspace().setIcon_forFile_options(
// IconCache.iconNamed("download" + progress + ".icns"), getAbsolute(), new NSUInteger(0));
// }
// }
// });
// }
// }
//
// private static String stringByAbbreviatingWithTildeInPath(String string) {
// return NSString.stringByAbbreviatingWithTildeInPath(string);
// }
//
// private static String stringByExpandingTildeInPath(String string) {
// return NSString.stringByExpandingTildeInPath(string);
// }
/**
*
*/
private static Map<String, String> defaultApplicationCache
= Collections.<String, String>synchronizedMap(new LRUMap(20) {
@Override
protected boolean removeLRU(AbstractLinkedMap.LinkEntry entry) {
log.debug("Removing from cache:" + entry);
return true;
}
});
// /**
// * The default application for this file as set by the launch services
// *
// * @return The bundle identifier of the default application to open the file of this type or null if unknown
// */
// @Override
// public String getDefaultApplication() {
// final String extension = this.getExtension();
// if(!defaultApplicationCache.containsKey(extension)) {
// if(StringUtils.isEmpty(extension)) {
// defaultApplicationCache.put(extension, null);
// }
// else {
// final String path = this.applicationForExtension(extension);
// if(StringUtils.isEmpty(path)) {
// defaultApplicationCache.put(extension, null);
// }
// else {
// defaultApplicationCache.put(extension, NSBundle.bundleWithPath(path).bundleIdentifier());
// }
// }
// }
// return defaultApplicationCache.get(extension);
// }
/**
* Uses LSGetApplicationForInfo
*
* @param extension
* @return Null if not found
*/
protected native String applicationForExtension(String extension);
/**
* Caching map between application bundle identifiers and
* file type extensions.
*/
private static Map<String, List<String>> defaultApplicationListCache
= Collections.<String, List<String>>synchronizedMap(new LRUMap(20) {
@Override
protected boolean removeLRU(AbstractLinkedMap.LinkEntry entry) {
log.debug("Removing from cache:" + entry);
return true;
}
});
/**
* @eturn All of the application bundle identifiers that are capable of handling
* the specified content type in the specified roles.
*/
@Override
public List<String> getDefaultApplications() {
final String extension = this.getExtension();
if(StringUtils.isEmpty(extension)) {
return Collections.emptyList();
}
if(!defaultApplicationListCache.containsKey(extension)) {
final List<String> applications = new ArrayList<String>(Arrays.asList(this.applicationListForExtension(extension)));
// Because of the different API used the default opening application may not be included
// in the above list returned. Always add the default application anyway.
final String defaultApplication = this.applicationForExtension(extension);
if(null != defaultApplication) {
if(!applications.contains(defaultApplication)) {
applications.add(defaultApplication);
}
}
defaultApplicationListCache.put(extension, applications);
}
return defaultApplicationListCache.get(extension);
}
/**
* Uses LSCopyAllRoleHandlersForContentType
*
* @param extension
* @return Empty array if none found
*/
protected native String[] applicationListForExtension(String extension);
// @Override
// public boolean open() {
// return NSWorkspace.sharedWorkspace().openFile(this.getAbsolute());
// }
//
// /**
// * Post a download finished notification to the distributed notification center. Will cause the
// * download folder to bounce just once.
// */
// @Override
// public void bounce() {
// NSDistributedNotificationCenter.defaultCenter().postNotification(
// NSNotification.notificationWithName("com.apple.DownloadFileFinished", this.getAbsolute())
// );
// }
@Override
public String toString() {
return this.toURL();
}
@Override
public void bounce() {
// TODO Auto-generated method stub
}
@Override
public boolean open() {
// TODO Auto-generated method stub
return false;
}
@Override
public void setIcon(int progress) {
// TODO Auto-generated method stub
}
@Override
public void trash() {
// TODO Auto-generated method stub
}
@Override
public void writePermissions(Permission perm, boolean recursive) {
// TODO Auto-generated method stub
}
// @Override
// public String toURL() {
// return stringByAbbreviatingWithTildeInPath(this.getAbsolute());
// }
//
// @Override
// public boolean isExecutable() {
// return NSFileManager.defaultManager().isExecutableFileAtPath(this.getAbsolute());
// }
//
// @Override
// public boolean isReadable() {
// return NSFileManager.defaultManager().isReadableFileAtPath(this.getAbsolute());
// }
//
// @Override
// public boolean isWritable() {
// return NSFileManager.defaultManager().isWritableFileAtPath(this.getAbsolute());
// }
}