de.invation.code.toval.os.WindowsUtils Maven / Gradle / Ivy
/*
* Copyright (c) 2015, Thomas Stocker
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted (subject to the limitations in the disclaimer
* below) 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 IIG Telematics, Uni Freiburg nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
* THIS LICENSE. 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 BELIABLE 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 de.invation.code.toval.os;
import de.invation.code.toval.os.WindowsRegistry.Hive;
import de.invation.code.toval.os.WindowsRegistry.RegistryException;
import java.io.File;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Utils class for Windows operating system regarding functionalities and
* properties.
*
* @version 1.0
* @author Adrian Lange
*/
public final class WindowsUtils extends OSUtils {
private static WindowsUtils instance = null;
/**
* Default Windows line separator
*/
public static final String WINDOWS_LINE_SEPARATOR = "\r\n";
private static final String SOFTWARE = "Software";
private static final String CLASSES = "Classes";
private static final String SHELL = "shell";
private static final String OPEN = "open";
private static final String COMMAND = "command";
private static final String SOFTWARE_CLASSES_PATH = WindowsRegistry.REG_PATH_SEPARATOR + SOFTWARE + WindowsRegistry.REG_PATH_SEPARATOR + CLASSES + WindowsRegistry.REG_PATH_SEPARATOR;
private static final String SHELL_PATH = WindowsRegistry.REG_PATH_SEPARATOR + SHELL;
private static final String SHELL_OPEN_PATH = SHELL_PATH + WindowsRegistry.REG_PATH_SEPARATOR + OPEN;
private static final String SHELL_OPEN_COMMAND_PATH = SHELL_OPEN_PATH + WindowsRegistry.REG_PATH_SEPARATOR + COMMAND;
private static final Pattern PATTERN_TEXT_BETWEEN_QUOTES = Pattern.compile("\"([^\"]*)\"");
private WindowsUtils() {
}
/**
* Checks if the given extension is already registered.
*
* @param fileTypeExtension File extension with leading dot, e.g.
* .bar.
* @return true if extension is registered, false
* otherwise.
* @throws RegistryException
*/
@Override
public boolean isFileExtensionRegistered(String fileTypeExtension) throws RegistryException, OSException {
if (!isApplicable()) {
return false;
}
// sanitize file extension
fileTypeExtension = sanitizeFileExtension(fileTypeExtension);
String[] hives = {Hive.HKEY_CURRENT_USER + SOFTWARE_CLASSES_PATH, Hive.HKEY_LOCAL_MACHINE + SOFTWARE_CLASSES_PATH, Hive.HKEY_CLASSES_ROOT + "\\"};
for (String h : hives) {
List subkeys = WindowsRegistry.readSubkeys(h);
if (subkeys.contains(fileTypeExtension)) {
return true;
}
}
return false;
}
/**
* Returns singleton instance of {@link OSUtils}.
*
* @return instance
*/
public static synchronized WindowsUtils instance() {
if (instance == null) {
instance = new WindowsUtils();
}
return instance;
}
/**
* Returns the associated application for a given extension.
*
* @param fileTypeExtension File extension with leading dot, e.g.
* .bar.
* @return {@link String} with path to associated application or
* null if file extension is not registered or can't be read.
* @throws RegistryException If Registry can't be read.
*/
@Override
public String getFileExtension(String fileTypeExtension) throws RegistryException, OSException {
if (!isApplicable() || !isFileExtensionRegistered(fileTypeExtension)) {
return null;
}
// sanitize file extension
fileTypeExtension = sanitizeFileExtension(fileTypeExtension);
Hive[] hives = {Hive.HKEY_CURRENT_USER, Hive.HKEY_LOCAL_MACHINE};
// get fileTypeName
String fileTypeName = null;
for (Hive h : hives) {
if (WindowsRegistry.existsKey(h.getName() + SOFTWARE_CLASSES_PATH + fileTypeExtension)) {
fileTypeName = WindowsRegistry.readValue(h.getName() + SOFTWARE_CLASSES_PATH + fileTypeExtension, WindowsRegistry.DEFAULT_KEY_NAME);
}
}
// get file association
if (fileTypeName != null) {
for (Hive h : hives) {
if (WindowsRegistry.existsKey(h.getName() + SOFTWARE_CLASSES_PATH + fileTypeName + SHELL_OPEN_COMMAND_PATH)) {
String fileTypeAssociation = WindowsRegistry.readValue(h.getName() + SOFTWARE_CLASSES_PATH + fileTypeName + SHELL_OPEN_COMMAND_PATH, WindowsRegistry.DEFAULT_KEY_NAME);
Matcher m = PATTERN_TEXT_BETWEEN_QUOTES.matcher(fileTypeAssociation);
// If exists return first string between quotes
while (m.find()) {
return m.group(1);
}
// otherwise return complete file association string
return fileTypeAssociation;
}
}
}
return null;
}
/**
* Returns true if current OS is Windows and this class can be
* used.
*
* @return true if OS is Windows, false otherwise.
*/
@Override
public boolean isApplicable() {
return getCurrentOS() == OSType.OS_WINDOWS;
}
/**
* Registers a new file extension in the Windows registry.
*
* @param fileTypeName Name of the file extension. Must be atomic, e.g.
* foocorp.fooapp.v1.
* @param fileTypeExtension File extension with leading dot, e.g.
* .bar.
* @param application Path to the application, which should open the new
* file extension.
* @return true if registration was successful,
* false otherwise.
* @throws RegistryException If keys can't be created or values can't be
* written.
*/
@Override
public boolean registerFileExtension(String fileTypeName, String fileTypeExtension, String application) throws RegistryException, OSException {
if (!isApplicable()) {
return false;
}
// sanitize file extension
fileTypeExtension = sanitizeFileExtension(fileTypeExtension);
// create path to linked application
String applicationPath = toWindowsPath(new File (application).getAbsolutePath());
// Set registry hive
WindowsRegistry.Hive hive = WindowsRegistry.Hive.HKEY_CURRENT_USER;
// create programmatic identifier
WindowsRegistry.createKey(hive.getName() + SOFTWARE_CLASSES_PATH + fileTypeName);
// create verb to open file type
WindowsRegistry.createKey(hive.getName() + SOFTWARE_CLASSES_PATH + fileTypeName + SHELL_OPEN_COMMAND_PATH);
WindowsRegistry.writeValue(hive.getName() + SOFTWARE_CLASSES_PATH + fileTypeName + SHELL_OPEN_COMMAND_PATH, WindowsRegistry.DEFAULT_KEY_NAME, "\"" + applicationPath + "\" \"%1\"");
// associate with file extension
WindowsRegistry.createKey(hive.getName() + SOFTWARE_CLASSES_PATH + fileTypeExtension);
WindowsRegistry.writeValue(hive.getName() + SOFTWARE_CLASSES_PATH + fileTypeExtension, WindowsRegistry.DEFAULT_KEY_NAME, fileTypeName);
return true;
}
/**
* Sanitizes file extension such that it can be used in the Windows
* Registry.
*
* @param fileTypeExtension Extension to sanitize
* @return Sanitized file extension
*/
private String sanitizeFileExtension(String fileTypeExtension) throws OSException {
// Remove whitespaces
String newFileTypeExtension = fileTypeExtension.replaceAll("\\s+", "");
// to lower case
newFileTypeExtension = newFileTypeExtension.toLowerCase();
/*
* Check if name contains multiple dots and if so, just take the last
* part. Also adds a dot before last part.
*/
String[] splittedFileExtension = newFileTypeExtension.split("\\.");
if (newFileTypeExtension.length() == 0 || splittedFileExtension.length == 0) {
throw new OSException("The given file extension \"" + fileTypeExtension + "\" is too short.");
}
newFileTypeExtension = "." + splittedFileExtension[splittedFileExtension.length - 1];
return newFileTypeExtension;
}
/**
* Replaces all / in a given path by a \.
*
* @param path Path to convert to the Windows format
* @return Given path in the Windows path format
*/
public String toWindowsPath(String path) {
return path.replaceAll("/", WindowsRegistry.REG_PATH_SEPARATOR_REGEX);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy