uk.gov.nationalarchives.droid.gui.action.OpenContainingFolderAction Maven / Gradle / Ivy
/**
* Copyright (c) 2016, The National Archives
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the The National Archives nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package uk.gov.nationalarchives.droid.gui.action;
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import uk.gov.nationalarchives.droid.profile.ProfileResourceNode;
/**
* @author a-mpalmer
*
*/
public class OpenContainingFolderAction {
private static final String FILE_URI_PREFIX = "file:/";
/**
* Constructor.
*/
public OpenContainingFolderAction() {
}
/**
* Opens the selected resource's containing folders.
* @param nodes - the list of nodes to open.
*/
public void open(final List nodes) {
if (Desktop.isDesktopSupported()) {
Set folderPaths = getClosestFolderPaths(nodes);
openFolders(folderPaths);
}
}
private void openFolders(final Set locations) {
Desktop desktop = Desktop.getDesktop();
for (String path : locations) {
File folder = new File(path);
if (folder.exists() && folder.isDirectory()) {
try {
desktop.open(folder);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
private Set getClosestFolderPaths(final List nodes) {
final Set closestFolderPaths = new HashSet();
for (ProfileResourceNode node : nodes) {
String closestFolderPath = getClosestFolderPath(getClosestFilePath(node.getUri()));
if (closestFolderPath != null && !closestFolderPath.isEmpty()) {
closestFolderPaths.add(closestFolderPath);
}
}
return closestFolderPaths;
}
private String getClosestFolderPath(final String filePath) {
String closestFolderPath = null;
final File theFile = new File(filePath);
if (theFile.exists()) {
File parentFolder = theFile.getParentFile();
closestFolderPath = parentFolder == null ? null : parentFolder.getAbsolutePath();
}
return closestFolderPath;
}
private String getClosestFilePath(final URI location) {
final String path = java.net.URLDecoder.decode(location.toString());
final int filePrefixEnd = path.indexOf(FILE_URI_PREFIX) + FILE_URI_PREFIX.length();
final int firstPling = path.indexOf('!', filePrefixEnd);
final int endOfFilePath = firstPling > 0 ? firstPling : path.length();
final String uriPath = path.substring(filePrefixEnd, endOfFilePath);
// does it have a windows drive letter or UNC path?
return path.charAt(filePrefixEnd + 1) == ':' || path.startsWith("///")
? uriPath
: '/' + uriPath; // a unix path, which will require an initial forward slash:
}
}