AppDataDirectory: Move from wallettemplate/.utils to core/.utils

This allows usage in both wallettemplate and tools and replaces
similar code in BlockFileLoader.java in core.
Requires minor back-port of Path.of() functionality from JDK11.
This commit is contained in:
Sean Gilligan 2019-06-10 23:09:11 -07:00 committed by Andreas Schildbach
parent d446951ceb
commit 3c5744a6cb
4 changed files with 108 additions and 17 deletions

View file

@ -14,16 +14,25 @@
* limitations under the License.
*/
package wallettemplate.utils;
package org.bitcoinj.utils;
import org.bitcoinj.core.Utils;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
/**
* Find/create App Data Directory in correct platform-specific location.
* This class is based on the conventions used in Bitcoin Core which
* uses the following locations:
* <dl>
* <dt>Windows</dt><dd>{@code ${APPDATA}/.bitcoin}</dd>
* <dt>macOS</dt><dd>{@code ${HOME}/Library/Application Support/Bitcoin}</dd>
* <dt>Linux</dt><dd>{@code ${HOME}/.bitcoin}</dd>
* </dl>
* Note that {@code appName} is converted to lower-case on Windows and Linux/Unix.
*/
public class AppDataDirectory {
@ -45,19 +54,36 @@ public class AppDataDirectory {
return applicationDataDirectory;
}
private static Path getPath(String appName) {
/**
* Return the Path to the application data directory without making
* sure it exists or creating it. (No disk I/O)
*
* @param appName The name of the current application
* @return Path to the application data directory
*/
public static Path getPath(String appName) {
final Path applicationDataDirectory;
if (Utils.isWindows()) {
applicationDataDirectory = Path.of(System.getenv("APPDATA"), appName.toLowerCase());
applicationDataDirectory = pathOf(System.getenv("APPDATA"), appName.toLowerCase());
} else if (Utils.isMac()) {
applicationDataDirectory = Path.of(System.getProperty("user.home"),"Library/Application Support", appName);
applicationDataDirectory = pathOf(System.getProperty("user.home"),"Library/Application Support", appName);
} else if (Utils.isLinux()) {
applicationDataDirectory = Path.of(System.getProperty("user.home"), "." + appName.toLowerCase());
applicationDataDirectory = pathOf(System.getProperty("user.home"), "." + appName.toLowerCase());
} else {
// Unknown, assume unix-like
applicationDataDirectory = Path.of(System.getProperty("user.home"), "." + appName.toLowerCase());
applicationDataDirectory = pathOf(System.getProperty("user.home"), "." + appName.toLowerCase());
}
return applicationDataDirectory;
}
/**
* Create a {@code Path} by joining path strings. Same functionality as Path.of() in JDK 11+
* @param first A base path string
* @param additional additional components to add
* @return the joined {@code Path}
*/
private static Path pathOf(String first, String... additional) {
return FileSystems.getDefault().getPath(first, additional);
}
}

View file

@ -71,16 +71,9 @@ public class BlockFileLoader implements Iterable<Block>, Iterator<Block> {
}
public static File defaultBlocksDir() {
final File defaultBlocksDir;
if (Utils.isWindows()) {
defaultBlocksDir = new File(System.getenv("APPDATA") + "\\.bitcoin\\blocks\\");
} else if (Utils.isMac()) {
defaultBlocksDir = new File(System.getProperty("user.home") + "/Library/Application Support/Bitcoin/blocks/");
} else if (Utils.isLinux()) {
defaultBlocksDir = new File(System.getProperty("user.home") + "/.bitcoin/blocks/");
} else {
throw new RuntimeException("Unsupported system");
}
File defaultBlocksDir = AppDataDirectory.getPath("Bitcoin").resolve("blocks").toFile();
if (!defaultBlocksDir.isDirectory())
throw new RuntimeException("Default blocks directory not found");
return defaultBlocksDir;
}

View file

@ -0,0 +1,72 @@
/*
* Copyright 2019 Michael Sean Gilligan
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.bitcoinj.utils;
import org.bitcoinj.core.Utils;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
/**
* Basic test of AppDataDirectory
*/
public class AppDataDirectoryTest {
private static final String HOMEDIR = System.getProperty("user.home");
private static final String WINAPPDATA = System.getenv("APPDATA");
@Test
public void worksOnCurrentPlatform() {
final String appName = "bitcoinj";
String path = AppDataDirectory.get(appName).toString();
if (Utils.isWindows()) {
assertEquals("Path wrong on Mac", winPath(appName), path);
} else if (Utils.isMac()) {
assertEquals("Path wrong on Mac", macPath(appName), path);
} else if (Utils.isLinux()) {
assertEquals("Path wrong on Linux", unixPath(appName), path);
} else {
assertEquals("Path wrong on unknown/default", unixPath(appName), path);
}
}
@Test
public void worksOnCurrentPlatformForBitcoinCore() {
final String appName = "Bitcoin";
String path = AppDataDirectory.get(appName).toString();
if (Utils.isWindows()) {
assertEquals("Path wrong on Mac", winPath(appName), path);
} else if (Utils.isMac()) {
assertEquals("Path wrong on Mac", macPath(appName), path);
} else if (Utils.isLinux()) {
assertEquals("Path wrong on Linux", unixPath(appName), path);
} else {
assertEquals("Path wrong on unknown/default", unixPath(appName), path);
}
}
private static String winPath(String appName) {
return WINAPPDATA + "\\." + appName.toLowerCase();
}
private static String macPath(String appName) {
return HOMEDIR + "/Library/Application Support/" + appName;
}
private static String unixPath(String appName) {
return HOMEDIR + "/." + appName.toLowerCase();
}
}

View file

@ -18,6 +18,7 @@ package wallettemplate;
import com.google.common.util.concurrent.*;
import javafx.scene.input.*;
import org.bitcoinj.utils.AppDataDirectory;
import org.bitcoinj.core.NetworkParameters;
import org.bitcoinj.core.Utils;
import org.bitcoinj.kits.WalletAppKit;
@ -35,7 +36,6 @@ import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import wallettemplate.controls.NotificationBarPane;
import wallettemplate.utils.AppDataDirectory;
import wallettemplate.utils.GuiUtils;
import wallettemplate.utils.TextFieldValidator;