[6380] | 1 | // License: GPL. For details, see LICENSE file.
|
---|
[1023] | 2 | package org.openstreetmap.josm.tools;
|
---|
| 3 |
|
---|
[4998] | 4 | import static org.openstreetmap.josm.tools.I18n.tr;
|
---|
[13647] | 5 | import static org.openstreetmap.josm.tools.Utils.getSystemEnv;
|
---|
| 6 | import static org.openstreetmap.josm.tools.Utils.getSystemProperty;
|
---|
[4998] | 7 |
|
---|
[6682] | 8 | import java.awt.Desktop;
|
---|
[1023] | 9 | import java.awt.event.KeyEvent;
|
---|
[5850] | 10 | import java.io.BufferedReader;
|
---|
[4153] | 11 | import java.io.File;
|
---|
[1023] | 12 | import java.io.IOException;
|
---|
[13204] | 13 | import java.io.InputStream;
|
---|
[6682] | 14 | import java.net.URISyntaxException;
|
---|
[7082] | 15 | import java.nio.charset.StandardCharsets;
|
---|
[7314] | 16 | import java.nio.file.Files;
|
---|
[7315] | 17 | import java.nio.file.Path;
|
---|
[7314] | 18 | import java.nio.file.Paths;
|
---|
[12241] | 19 | import java.security.KeyStoreException;
|
---|
| 20 | import java.security.NoSuchAlgorithmException;
|
---|
| 21 | import java.security.cert.CertificateException;
|
---|
| 22 | import java.security.cert.CertificateFactory;
|
---|
| 23 | import java.security.cert.X509Certificate;
|
---|
[6103] | 24 | import java.util.Arrays;
|
---|
[14144] | 25 | import java.util.Collection;
|
---|
| 26 | import java.util.HashSet;
|
---|
[11162] | 27 | import java.util.Locale;
|
---|
[16911] | 28 | import java.util.Optional;
|
---|
[14144] | 29 | import java.util.Set;
|
---|
[12830] | 30 | import java.util.concurrent.ExecutionException;
|
---|
[1023] | 31 |
|
---|
[14148] | 32 | import org.openstreetmap.josm.data.Preferences;
|
---|
[13450] | 33 | import org.openstreetmap.josm.io.CertificateAmendment.NativeCertAmend;
|
---|
[12846] | 34 | import org.openstreetmap.josm.spi.preferences.Config;
|
---|
[6310] | 35 |
|
---|
[1023] | 36 | /**
|
---|
[12219] | 37 | * {@code PlatformHook} implementation for Unix systems.
|
---|
| 38 | * @since 1023
|
---|
[2376] | 39 | */
|
---|
[1023] | 40 | public class PlatformHookUnixoid implements PlatformHook {
|
---|
[6070] | 41 |
|
---|
[5994] | 42 | private String osDescription;
|
---|
[6070] | 43 |
|
---|
[4897] | 44 | @Override
|
---|
[12776] | 45 | public Platform getPlatform() {
|
---|
| 46 | return Platform.UNIXOID;
|
---|
| 47 | }
|
---|
| 48 |
|
---|
| 49 | @Override
|
---|
[6443] | 50 | public void preStartupHook() {
|
---|
[14177] | 51 | // See #12022, #16666 - Disable GNOME ATK Java wrapper as it causes a lot of serious trouble
|
---|
| 52 | if (isDebianOrUbuntu()) {
|
---|
| 53 | if (Utils.getJavaVersion() >= 9) {
|
---|
| 54 | // TODO: find a way to disable ATK wrapper on Java >= 9
|
---|
| 55 | // We should probably be able to do that by embedding a no-op AccessibilityProvider in our jar
|
---|
| 56 | // so that it is loaded by ServiceLoader without error
|
---|
| 57 | // But this require to compile at least one class with Java 9
|
---|
| 58 | } else {
|
---|
| 59 | // Java 8 does a simple Class.newInstance() from system classloader
|
---|
| 60 | Utils.updateSystemProperty("javax.accessibility.assistive_technologies", "java.lang.Object");
|
---|
| 61 | }
|
---|
[9750] | 62 | }
|
---|
[1169] | 63 | }
|
---|
[4897] | 64 |
|
---|
| 65 | @Override
|
---|
[1169] | 66 | public void openUrl(String url) throws IOException {
|
---|
[12846] | 67 | for (String program : Config.getPref().getList("browser.unix",
|
---|
[6682] | 68 | Arrays.asList("xdg-open", "#DESKTOP#", "$BROWSER", "gnome-open", "kfmclient openURL", "firefox"))) {
|
---|
[1169] | 69 | try {
|
---|
[6682] | 70 | if ("#DESKTOP#".equals(program)) {
|
---|
[15543] | 71 | Desktop.getDesktop().browse(Utils.urlToURI(url));
|
---|
[6682] | 72 | } else if (program.startsWith("$")) {
|
---|
| 73 | program = System.getenv().get(program.substring(1));
|
---|
| 74 | Runtime.getRuntime().exec(new String[]{program, url});
|
---|
| 75 | } else {
|
---|
| 76 | Runtime.getRuntime().exec(new String[]{program, url});
|
---|
| 77 | }
|
---|
[1169] | 78 | return;
|
---|
[7004] | 79 | } catch (IOException | URISyntaxException e) {
|
---|
[12620] | 80 | Logging.warn(e);
|
---|
[1169] | 81 | }
|
---|
| 82 | }
|
---|
| 83 | }
|
---|
[1023] | 84 |
|
---|
[4897] | 85 | @Override
|
---|
[1169] | 86 | public void initSystemShortcuts() {
|
---|
[8518] | 87 | // CHECKSTYLE.OFF: LineLength
|
---|
[4897] | 88 | // TODO: Insert system shortcuts here. See Windows and especially OSX to see how to.
|
---|
[8513] | 89 | for (int i = KeyEvent.VK_F1; i <= KeyEvent.VK_F12; ++i) {
|
---|
[8518] | 90 | Shortcut.registerSystemShortcut("screen:toogle"+i, tr("reserved"), i, KeyEvent.CTRL_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)
|
---|
| 91 | .setAutomatic();
|
---|
[8513] | 92 | }
|
---|
[8518] | 93 | Shortcut.registerSystemShortcut("system:reset", tr("reserved"), KeyEvent.VK_DELETE, KeyEvent.CTRL_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)
|
---|
| 94 | .setAutomatic();
|
---|
| 95 | Shortcut.registerSystemShortcut("system:resetX", tr("reserved"), KeyEvent.VK_BACK_SPACE, KeyEvent.CTRL_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)
|
---|
| 96 | .setAutomatic();
|
---|
| 97 | // CHECKSTYLE.ON: LineLength
|
---|
[1169] | 98 | }
|
---|
[6920] | 99 |
|
---|
[4897] | 100 | @Override
|
---|
[2376] | 101 | public String getDefaultStyle() {
|
---|
[2371] | 102 | return "javax.swing.plaf.metal.MetalLookAndFeel";
|
---|
| 103 | }
|
---|
[4153] | 104 |
|
---|
[6103] | 105 | /**
|
---|
[16911] | 106 | * Returns desktop environment based on the environment variable {@code XDG_CURRENT_DESKTOP}.
|
---|
| 107 | * @return desktop environment.
|
---|
| 108 | */
|
---|
| 109 | public Optional<String> getDesktopEnvironment() {
|
---|
[16924] | 110 | return Optional.ofNullable(getSystemEnv("XDG_CURRENT_DESKTOP")).filter(s -> !s.isEmpty());
|
---|
[16911] | 111 | }
|
---|
| 112 |
|
---|
| 113 | /**
|
---|
[10166] | 114 | * Determines if the distribution is Debian or Ubuntu, or a derivative.
|
---|
| 115 | * @return {@code true} if the distribution is Debian, Ubuntu or Mint, {@code false} otherwise
|
---|
| 116 | */
|
---|
| 117 | public static boolean isDebianOrUbuntu() {
|
---|
| 118 | try {
|
---|
| 119 | String dist = Utils.execOutput(Arrays.asList("lsb_release", "-i", "-s"));
|
---|
| 120 | return "Debian".equalsIgnoreCase(dist) || "Ubuntu".equalsIgnoreCase(dist) || "Mint".equalsIgnoreCase(dist);
|
---|
[12830] | 121 | } catch (IOException | ExecutionException | InterruptedException e) {
|
---|
[10627] | 122 | // lsb_release is not available on all Linux systems, so don't log at warning level
|
---|
[12620] | 123 | Logging.debug(e);
|
---|
[10166] | 124 | return false;
|
---|
| 125 | }
|
---|
| 126 | }
|
---|
| 127 |
|
---|
| 128 | /**
|
---|
[6850] | 129 | * Get the package name including detailed version.
|
---|
[7314] | 130 | * @param packageNames The possible package names (when a package can have different names on different distributions)
|
---|
[6850] | 131 | * @return The package name and package version if it can be identified, null otherwise
|
---|
[7314] | 132 | * @since 7314
|
---|
[6850] | 133 | */
|
---|
[11747] | 134 | public static String getPackageDetails(String... packageNames) {
|
---|
[6850] | 135 | try {
|
---|
[10378] | 136 | // CHECKSTYLE.OFF: SingleSpaceSeparator
|
---|
[11096] | 137 | boolean dpkg = Paths.get("/usr/bin/dpkg-query").toFile().exists();
|
---|
| 138 | boolean eque = Paths.get("/usr/bin/equery").toFile().exists();
|
---|
| 139 | boolean rpm = Paths.get("/bin/rpm").toFile().exists();
|
---|
[10378] | 140 | // CHECKSTYLE.ON: SingleSpaceSeparator
|
---|
[7349] | 141 | if (dpkg || rpm || eque) {
|
---|
[7314] | 142 | for (String packageName : packageNames) {
|
---|
[10308] | 143 | String[] args;
|
---|
[7314] | 144 | if (dpkg) {
|
---|
| 145 | args = new String[] {"dpkg-query", "--show", "--showformat", "${Architecture}-${Version}", packageName};
|
---|
[7349] | 146 | } else if (eque) {
|
---|
| 147 | args = new String[] {"equery", "-q", "list", "-e", "--format=$fullversion", packageName};
|
---|
[7314] | 148 | } else {
|
---|
| 149 | args = new String[] {"rpm", "-q", "--qf", "%{arch}-%{version}", packageName};
|
---|
| 150 | }
|
---|
[12830] | 151 | try {
|
---|
| 152 | String version = Utils.execOutput(Arrays.asList(args));
|
---|
| 153 | if (version != null && !version.isEmpty()) {
|
---|
| 154 | return packageName + ':' + version;
|
---|
[12239] | 155 | }
|
---|
[12830] | 156 | } catch (ExecutionException e) {
|
---|
| 157 | // Package does not exist, continue
|
---|
| 158 | Logging.trace(e);
|
---|
[7314] | 159 | }
|
---|
| 160 | }
|
---|
[6962] | 161 | }
|
---|
[12830] | 162 | } catch (IOException | InterruptedException e) {
|
---|
[12620] | 163 | Logging.warn(e);
|
---|
[6850] | 164 | }
|
---|
[6962] | 165 | return null;
|
---|
[6850] | 166 | }
|
---|
[6920] | 167 |
|
---|
[6850] | 168 | /**
|
---|
[6103] | 169 | * Get the Java package name including detailed version.
|
---|
| 170 | *
|
---|
| 171 | * Some Java bugs are specific to a certain security update, so in addition
|
---|
| 172 | * to the Java version, we also need the exact package version.
|
---|
| 173 | *
|
---|
[7314] | 174 | * @return The package name and package version if it can be identified, null otherwise
|
---|
[6103] | 175 | */
|
---|
| 176 | public String getJavaPackageDetails() {
|
---|
[13647] | 177 | String home = getSystemProperty("java.home");
|
---|
[10580] | 178 | if (home.contains("java-8-openjdk") || home.contains("java-1.8.0-openjdk")) {
|
---|
| 179 | return getPackageDetails("openjdk-8-jre", "java-1_8_0-openjdk", "java-1.8.0-openjdk");
|
---|
| 180 | } else if (home.contains("java-9-openjdk") || home.contains("java-1.9.0-openjdk")) {
|
---|
[12830] | 181 | return getPackageDetails("openjdk-9-jre", "java-1_9_0-openjdk", "java-1.9.0-openjdk", "java-9-openjdk");
|
---|
[13695] | 182 | } else if (home.contains("java-10-openjdk")) {
|
---|
| 183 | return getPackageDetails("openjdk-10-jre", "java-10-openjdk");
|
---|
| 184 | } else if (home.contains("java-11-openjdk")) {
|
---|
| 185 | return getPackageDetails("openjdk-11-jre", "java-11-openjdk");
|
---|
| 186 | } else if (home.contains("java-openjdk")) {
|
---|
| 187 | return getPackageDetails("java-openjdk");
|
---|
[7349] | 188 | } else if (home.contains("icedtea")) {
|
---|
| 189 | return getPackageDetails("icedtea-bin");
|
---|
| 190 | } else if (home.contains("oracle")) {
|
---|
| 191 | return getPackageDetails("oracle-jdk-bin", "oracle-jre-bin");
|
---|
[6103] | 192 | }
|
---|
| 193 | return null;
|
---|
| 194 | }
|
---|
[6920] | 195 |
|
---|
[6850] | 196 | /**
|
---|
| 197 | * Get the Web Start package name including detailed version.
|
---|
| 198 | *
|
---|
[7314] | 199 | * OpenJDK packages are shipped with icedtea-web package,
|
---|
| 200 | * but its version generally does not match main java package version.
|
---|
[6920] | 201 | *
|
---|
[6850] | 202 | * Simply return {@code null} if there's no separate package for Java WebStart.
|
---|
| 203 | *
|
---|
| 204 | * @return The package name and package version if it can be identified, null otherwise
|
---|
| 205 | */
|
---|
| 206 | public String getWebStartPackageDetails() {
|
---|
[7314] | 207 | if (isOpenJDK()) {
|
---|
| 208 | return getPackageDetails("icedtea-netx", "icedtea-web");
|
---|
[6850] | 209 | }
|
---|
| 210 | return null;
|
---|
| 211 | }
|
---|
[6103] | 212 |
|
---|
[10734] | 213 | /**
|
---|
| 214 | * Get the Gnome ATK wrapper package name including detailed version.
|
---|
| 215 | *
|
---|
| 216 | * Debian and Ubuntu derivatives come with a pre-enabled accessibility software
|
---|
| 217 | * completely buggy that makes Swing crash in a lot of different ways.
|
---|
| 218 | *
|
---|
| 219 | * Simply return {@code null} if it's not found.
|
---|
| 220 | *
|
---|
| 221 | * @return The package name and package version if it can be identified, null otherwise
|
---|
| 222 | */
|
---|
| 223 | public String getAtkWrapperPackageDetails() {
|
---|
| 224 | if (isOpenJDK() && isDebianOrUbuntu()) {
|
---|
| 225 | return getPackageDetails("libatk-wrapper-java");
|
---|
| 226 | }
|
---|
| 227 | return null;
|
---|
| 228 | }
|
---|
| 229 |
|
---|
[12219] | 230 | private String buildOSDescription() {
|
---|
[13647] | 231 | String osName = getSystemProperty("os.name");
|
---|
[5850] | 232 | if ("Linux".equalsIgnoreCase(osName)) {
|
---|
| 233 | try {
|
---|
[8540] | 234 | // Try lsb_release (only available on LSB-compliant Linux systems,
|
---|
| 235 | // see https://www.linuxbase.org/lsb-cert/productdir.php?by_prod )
|
---|
[12411] | 236 | String line = exec("lsb_release", "-ds");
|
---|
[12217] | 237 | if (line != null && !line.isEmpty()) {
|
---|
| 238 | line = line.replaceAll("\"+", "");
|
---|
[15293] | 239 | line = line.replace("NAME=", ""); // strange code for some Gentoo's
|
---|
[12217] | 240 | if (line.startsWith("Linux ")) // e.g. Linux Mint
|
---|
| 241 | return line;
|
---|
| 242 | else if (!line.isEmpty())
|
---|
| 243 | return "Linux " + line;
|
---|
[5850] | 244 | }
|
---|
| 245 | } catch (IOException e) {
|
---|
[12620] | 246 | Logging.debug(e);
|
---|
[5877] | 247 | // Non LSB-compliant Linux system. List of common fallback release files: http://linuxmafia.com/faq/Admin/release-files.html
|
---|
| 248 | for (LinuxReleaseInfo info : new LinuxReleaseInfo[]{
|
---|
| 249 | new LinuxReleaseInfo("/etc/lsb-release", "DISTRIB_DESCRIPTION", "DISTRIB_ID", "DISTRIB_RELEASE"),
|
---|
| 250 | new LinuxReleaseInfo("/etc/os-release", "PRETTY_NAME", "NAME", "VERSION"),
|
---|
| 251 | new LinuxReleaseInfo("/etc/arch-release"),
|
---|
| 252 | new LinuxReleaseInfo("/etc/debian_version", "Debian GNU/Linux "),
|
---|
| 253 | new LinuxReleaseInfo("/etc/fedora-release"),
|
---|
| 254 | new LinuxReleaseInfo("/etc/gentoo-release"),
|
---|
[7314] | 255 | new LinuxReleaseInfo("/etc/redhat-release"),
|
---|
| 256 | new LinuxReleaseInfo("/etc/SuSE-release")
|
---|
[5877] | 257 | }) {
|
---|
| 258 | String description = info.extractDescription();
|
---|
| 259 | if (description != null && !description.isEmpty()) {
|
---|
| 260 | return "Linux " + description;
|
---|
| 261 | }
|
---|
| 262 | }
|
---|
[5850] | 263 | }
|
---|
| 264 | }
|
---|
| 265 | return osName;
|
---|
| 266 | }
|
---|
[6070] | 267 |
|
---|
[5994] | 268 | @Override
|
---|
| 269 | public String getOSDescription() {
|
---|
| 270 | if (osDescription == null) {
|
---|
| 271 | osDescription = buildOSDescription();
|
---|
| 272 | }
|
---|
| 273 | return osDescription;
|
---|
| 274 | }
|
---|
[6070] | 275 |
|
---|
[12219] | 276 | private static class LinuxReleaseInfo {
|
---|
[5877] | 277 | private final String path;
|
---|
| 278 | private final String descriptionField;
|
---|
| 279 | private final String idField;
|
---|
| 280 | private final String releaseField;
|
---|
| 281 | private final boolean plainText;
|
---|
| 282 | private final String prefix;
|
---|
[6070] | 283 |
|
---|
[12219] | 284 | LinuxReleaseInfo(String path, String descriptionField, String idField, String releaseField) {
|
---|
[5877] | 285 | this(path, descriptionField, idField, releaseField, false, null);
|
---|
| 286 | }
|
---|
| 287 |
|
---|
[12219] | 288 | LinuxReleaseInfo(String path) {
|
---|
[5877] | 289 | this(path, null, null, null, true, null);
|
---|
| 290 | }
|
---|
| 291 |
|
---|
[12219] | 292 | LinuxReleaseInfo(String path, String prefix) {
|
---|
[5877] | 293 | this(path, null, null, null, true, prefix);
|
---|
| 294 | }
|
---|
[6070] | 295 |
|
---|
[5877] | 296 | private LinuxReleaseInfo(String path, String descriptionField, String idField, String releaseField, boolean plainText, String prefix) {
|
---|
| 297 | this.path = path;
|
---|
| 298 | this.descriptionField = descriptionField;
|
---|
| 299 | this.idField = idField;
|
---|
| 300 | this.releaseField = releaseField;
|
---|
| 301 | this.plainText = plainText;
|
---|
| 302 | this.prefix = prefix;
|
---|
| 303 | }
|
---|
| 304 |
|
---|
[12219] | 305 | @Override
|
---|
| 306 | public String toString() {
|
---|
[6070] | 307 | return "ReleaseInfo [path=" + path + ", descriptionField=" + descriptionField +
|
---|
[8846] | 308 | ", idField=" + idField + ", releaseField=" + releaseField + ']';
|
---|
[5877] | 309 | }
|
---|
[6070] | 310 |
|
---|
[5877] | 311 | /**
|
---|
| 312 | * Extracts OS detailed information from a Linux release file (/etc/xxx-release)
|
---|
| 313 | * @return The OS detailed information, or {@code null}
|
---|
| 314 | */
|
---|
| 315 | public String extractDescription() {
|
---|
| 316 | String result = null;
|
---|
| 317 | if (path != null) {
|
---|
[7315] | 318 | Path p = Paths.get(path);
|
---|
[11096] | 319 | if (p.toFile().exists()) {
|
---|
[7315] | 320 | try (BufferedReader reader = Files.newBufferedReader(p, StandardCharsets.UTF_8)) {
|
---|
[5877] | 321 | String id = null;
|
---|
| 322 | String release = null;
|
---|
| 323 | String line;
|
---|
| 324 | while (result == null && (line = reader.readLine()) != null) {
|
---|
| 325 | if (line.contains("=")) {
|
---|
[16643] | 326 | String[] tokens = line.split("=", -1);
|
---|
[5877] | 327 | if (tokens.length >= 2) {
|
---|
| 328 | // Description, if available, contains exactly what we need
|
---|
| 329 | if (descriptionField != null && descriptionField.equalsIgnoreCase(tokens[0])) {
|
---|
| 330 | result = Utils.strip(tokens[1]);
|
---|
| 331 | } else if (idField != null && idField.equalsIgnoreCase(tokens[0])) {
|
---|
| 332 | id = Utils.strip(tokens[1]);
|
---|
| 333 | } else if (releaseField != null && releaseField.equalsIgnoreCase(tokens[0])) {
|
---|
| 334 | release = Utils.strip(tokens[1]);
|
---|
| 335 | }
|
---|
| 336 | }
|
---|
| 337 | } else if (plainText && !line.isEmpty()) {
|
---|
| 338 | // Files composed of a single line
|
---|
| 339 | result = Utils.strip(line);
|
---|
| 340 | }
|
---|
| 341 | }
|
---|
| 342 | // If no description has been found, try to rebuild it with "id" + "release" (i.e. "name" + "version")
|
---|
| 343 | if (result == null && id != null && release != null) {
|
---|
[8846] | 344 | result = id + ' ' + release;
|
---|
[5877] | 345 | }
|
---|
| 346 | } catch (IOException e) {
|
---|
| 347 | // Ignore
|
---|
[12620] | 348 | Logging.trace(e);
|
---|
[5877] | 349 | }
|
---|
| 350 | }
|
---|
| 351 | }
|
---|
| 352 | // Append prefix if any
|
---|
| 353 | if (result != null && !result.isEmpty() && prefix != null && !prefix.isEmpty()) {
|
---|
| 354 | result = prefix + result;
|
---|
| 355 | }
|
---|
[8510] | 356 | if (result != null)
|
---|
| 357 | result = result.replaceAll("\"+", "");
|
---|
[5877] | 358 | return result;
|
---|
| 359 | }
|
---|
| 360 | }
|
---|
[6920] | 361 |
|
---|
[11162] | 362 | /**
|
---|
| 363 | * Get the dot directory <code>~/.josm</code>.
|
---|
| 364 | * @return the dot directory
|
---|
| 365 | */
|
---|
[11218] | 366 | private static File getDotDirectory() {
|
---|
[14148] | 367 | String dirName = "." + Preferences.getJOSMDirectoryBaseName().toLowerCase(Locale.ENGLISH);
|
---|
[13647] | 368 | return new File(getSystemProperty("user.home"), dirName);
|
---|
[11162] | 369 | }
|
---|
| 370 |
|
---|
| 371 | /**
|
---|
| 372 | * Returns true if the dot directory should be used for storing preferences,
|
---|
| 373 | * cache and user data.
|
---|
| 374 | * Currently this is the case, if the dot directory already exists.
|
---|
| 375 | * @return true if the dot directory should be used
|
---|
| 376 | */
|
---|
[11613] | 377 | private static boolean useDotDirectory() {
|
---|
[11162] | 378 | return getDotDirectory().exists();
|
---|
| 379 | }
|
---|
| 380 |
|
---|
[7206] | 381 | @Override
|
---|
[7829] | 382 | public File getDefaultCacheDirectory() {
|
---|
[11162] | 383 | if (useDotDirectory()) {
|
---|
| 384 | return new File(getDotDirectory(), "cache");
|
---|
| 385 | } else {
|
---|
[13647] | 386 | String xdgCacheDir = getSystemEnv("XDG_CACHE_HOME");
|
---|
[11162] | 387 | if (xdgCacheDir != null && !xdgCacheDir.isEmpty()) {
|
---|
[14148] | 388 | return new File(xdgCacheDir, Preferences.getJOSMDirectoryBaseName());
|
---|
[11162] | 389 | } else {
|
---|
[13647] | 390 | return new File(getSystemProperty("user.home") + File.separator +
|
---|
[14148] | 391 | ".cache" + File.separator + Preferences.getJOSMDirectoryBaseName());
|
---|
[11162] | 392 | }
|
---|
| 393 | }
|
---|
[7829] | 394 | }
|
---|
[7831] | 395 |
|
---|
| 396 | @Override
|
---|
| 397 | public File getDefaultPrefDirectory() {
|
---|
[11162] | 398 | if (useDotDirectory()) {
|
---|
| 399 | return getDotDirectory();
|
---|
| 400 | } else {
|
---|
[13647] | 401 | String xdgConfigDir = getSystemEnv("XDG_CONFIG_HOME");
|
---|
[11162] | 402 | if (xdgConfigDir != null && !xdgConfigDir.isEmpty()) {
|
---|
[14148] | 403 | return new File(xdgConfigDir, Preferences.getJOSMDirectoryBaseName());
|
---|
[11162] | 404 | } else {
|
---|
[13647] | 405 | return new File(getSystemProperty("user.home") + File.separator +
|
---|
[14148] | 406 | ".config" + File.separator + Preferences.getJOSMDirectoryBaseName());
|
---|
[11162] | 407 | }
|
---|
| 408 | }
|
---|
[7831] | 409 | }
|
---|
[7834] | 410 |
|
---|
| 411 | @Override
|
---|
| 412 | public File getDefaultUserDataDirectory() {
|
---|
[11162] | 413 | if (useDotDirectory()) {
|
---|
| 414 | return getDotDirectory();
|
---|
| 415 | } else {
|
---|
[13647] | 416 | String xdgDataDir = getSystemEnv("XDG_DATA_HOME");
|
---|
[11162] | 417 | if (xdgDataDir != null && !xdgDataDir.isEmpty()) {
|
---|
[14148] | 418 | return new File(xdgDataDir, Preferences.getJOSMDirectoryBaseName());
|
---|
[11162] | 419 | } else {
|
---|
[13647] | 420 | return new File(getSystemProperty("user.home") + File.separator +
|
---|
[14148] | 421 | ".local" + File.separator + "share" + File.separator + Preferences.getJOSMDirectoryBaseName());
|
---|
[11162] | 422 | }
|
---|
| 423 | }
|
---|
[7834] | 424 | }
|
---|
[8015] | 425 |
|
---|
[11642] | 426 | @Override
|
---|
[13450] | 427 | public X509Certificate getX509Certificate(NativeCertAmend certAmend)
|
---|
[12241] | 428 | throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
|
---|
[13693] | 429 | for (String dir : new String[] {"/etc/ssl/certs", "/usr/share/ca-certificates/mozilla"}) {
|
---|
| 430 | File f = new File(dir, certAmend.getFilename());
|
---|
| 431 | if (f.exists()) {
|
---|
| 432 | CertificateFactory fact = CertificateFactory.getInstance("X.509");
|
---|
| 433 | try (InputStream is = Files.newInputStream(f.toPath())) {
|
---|
| 434 | return (X509Certificate) fact.generateCertificate(is);
|
---|
| 435 | }
|
---|
[12241] | 436 | }
|
---|
| 437 | }
|
---|
| 438 | return null;
|
---|
| 439 | }
|
---|
[14144] | 440 |
|
---|
| 441 | @Override
|
---|
| 442 | public Collection<String> getPossiblePreferenceDirs() {
|
---|
| 443 | Set<String> locations = new HashSet<>();
|
---|
| 444 | locations.add("/usr/local/share/josm/");
|
---|
| 445 | locations.add("/usr/local/lib/josm/");
|
---|
| 446 | locations.add("/usr/share/josm/");
|
---|
| 447 | locations.add("/usr/lib/josm/");
|
---|
| 448 | return locations;
|
---|
| 449 | }
|
---|
[1023] | 450 | }
|
---|