All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.pepsoft.util.XDG Maven / Gradle / Ivy

The newest version!
/*
 * WorldPainter, a graphical and interactive map generator for Minecraft.
 * Copyright © 2011-2015  pepsoft.org, The Netherlands
 *
 * 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 3 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */

package org.pepsoft.util;

import org.pepsoft.util.mdc.MDCCapturingRuntimeException;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;

/**
 * Utility class for accessing the freedesktop.org "XDG Base Directory
 * Specification" directories as well as the "well known" user directories as
 * managed by the xdg-user-dirs tool.
 *
 * 

The string-typed constants are set whether or not the directory exists; * either to the configured value or a default, if applicable. The file-typed * constants are only set if the directory actually exists. * *

See * http://standards.freedesktop.org/basedir-spec/latest/ * and * http://www.freedesktop.org/wiki/Software/xdg-user-dirs/ * *

Created by Pepijn Schmitz on 19-03-15. */ public final class XDG { private XDG() { // Prevent instantiation } // Base dirs /** * The current user's home directory. Set to the value of the * {@code user.home} system property. */ public static final String HOME = System.getProperty("user.home"); /** * Defines the base directory relative to which user specific data files * should be stored. Set to the contents of the XDG_DATA_HOME environment * variable, or "{@link #HOME}/.local/share" if that variable is not present. */ public static final String XDG_DATA_HOME = System.getenv("XDG_DATA_HOME") != null ? System.getenv("XDG_DATA_HOME") : HOME + File.separatorChar + ".local" + File.separatorChar + "share"; /** * Defines the base directory relative to which user specific configuration * files should be stored. Set to the contents of the XDG_CONFIG_HOME * environment variable, or "{@link #HOME}/.config" if that variable is not present. */ public static final String XDG_CONFIG_HOME = System.getenv("XDG_CONFIG_HOME") != null ? System.getenv("XDG_CONFIG_HOME") : HOME + File.separatorChar + ".config"; /** * Defines the preference-ordered set of base directories to search for data * files in addition to the {@link #XDG_DATA_HOME} base directory. Set to * the contents of the XDG_DATA_DIRS environment variable, or * "/usr/local/share:/usr/share" if that variable is not present. */ public static final String XDG_DATA_DIRS = System.getenv("XDG_DATA_DIRS") != null ? System.getenv("XDG_DATA_DIRS") : File.separatorChar + "usr" + File.separatorChar + "local" + File.separatorChar + "share" + File.pathSeparatorChar + File.separatorChar + "usr" + File.separatorChar + "share"; /** * Defines the preference-ordered set of base directories to search for * configuration files in addition to the {@link #XDG_CONFIG_HOME} base * directory. Set to the contents of the XDG_CONFIG_DIRS environment * variable, or "/etc/xdg" if that variable is not present. */ public static final String XDG_CONFIG_DIRS = System.getenv("XDG_CONFIG_DIRS") != null ? System.getenv("XDG_CONFIG_DIRS") : File.separatorChar + "etc" + File.separatorChar + "xdg"; /** * Defines the base directory relative to which user specific non-essential * data files should be stored. Set to the contents of the XDG_CACHE_HOME * environment variable, or "{@link #HOME}/.cache" if that variable is not present. */ public static final String XDG_CACHE_HOME = System.getenv("XDG_CACHE_HOME") != null ? System.getenv("XDG_CACHE_HOME") : HOME + File.separatorChar + ".cache"; /** * Defines the base directory relative to which user-specific non-essential * runtime files and other file objects (such as sockets, named pipes, ...) * should be stored. Set to the contents of the XDG_RUNTIME_DIR environment * variable, or {@code null} if that variable is not present. */ public static final String XDG_RUNTIME_DIR = System.getenv("XDG_RUNTIME_DIR"); /** * {@link #XDG_DATA_HOME} as a {@link File} object, but only if that * directory actually exists. {@code null} otherwise. */ public static final File XDG_DATA_HOME_FILE = new File(XDG_DATA_HOME).isDirectory() ? new File(XDG_DATA_HOME) : null; /** * {@link #XDG_CONFIG_HOME} as a {@link File} object, but only if that * directory actually exists. {@code null} otherwise. */ public static final File XDG_CONFIG_HOME_FILE = new File(XDG_CONFIG_HOME).isDirectory() ? new File(XDG_CONFIG_HOME) : null; /** * {@link #XDG_CACHE_HOME} as a {@link File} object, but only if that * directory actually exists. {@code null} otherwise. */ public static final File XDG_CACHE_HOME_FILE = new File(XDG_CACHE_HOME).isDirectory() ? new File(XDG_CACHE_HOME) : null; /** * {@link #XDG_RUNTIME_DIR} as a {@link File} object, but only if * {@code XDG_RUNTIME_DIR} is not {@code null} and that * directory actually exists. {@code null} otherwise. */ public static final File XDG_RUNTIME_DIR_FILE = XDG_RUNTIME_DIR != null ? (new File(XDG_RUNTIME_DIR).isDirectory() ? new File(XDG_RUNTIME_DIR) : null) : null; // User dirs /** * The location of the "desktop" well known user directory, as specified * in the appropriate system or user config file, or {@code null} if * it is not configured. */ public static final String XDG_DESKTOP_DIR; /** * The location of the "documents" well known user directory, as specified * in the appropriate system or user config file, or {@code null} if * it is not configured. */ public static final String XDG_DOCUMENTS_DIR; /** * The location of the "download" well known user directory, as specified * in the appropriate system or user config file, or {@code null} if * it is not configured. */ public static final String XDG_DOWNLOAD_DIR; /** * The location of the "music" well known user directory, as specified * in the appropriate system or user config file, or {@code null} if * it is not configured. */ public static final String XDG_MUSIC_DIR; /** * The location of the "pictures" well known user directory, as specified * in the appropriate system or user config file, or {@code null} if * it is not configured. */ public static final String XDG_PICTURES_DIR; /** * The location of the "public share" well known user directory, as specified * in the appropriate system or user config file, or {@code null} if * it is not configured. */ public static final String XDG_PUBLICSHARE_DIR; /** * The location of the "templates" well known user directory, as specified * in the appropriate system or user config file, or {@code null} if * it is not configured. */ public static final String XDG_TEMPLATES_DIR; /** * The location of the "videos" well known user directory, as specified * in the appropriate system or user config file, or {@code null} if * it is not configured. */ public static final String XDG_VIDEOS_DIR; static { Properties userDirs = new Properties(); String[] configDirs = XDG_CONFIG_DIRS.split(File.pathSeparator); for (String configDir: configDirs) { File userDirFile = new File(configDir, "user-dirs.default"); if (userDirFile.isFile()) { readShellVarScript(userDirFile, userDirs); } } File userConfigFile = new File(XDG_CONFIG_HOME, "user-dirs.dirs"); if (userConfigFile.isFile()) { readShellVarScript(userConfigFile, userDirs); } XDG_DESKTOP_DIR = userDirs.getProperty("XDG_DESKTOP_DIR"); XDG_DOCUMENTS_DIR = userDirs.getProperty("XDG_DOCUMENTS_DIR"); XDG_DOWNLOAD_DIR = userDirs.getProperty("XDG_DOWNLOAD_DIR"); XDG_MUSIC_DIR = userDirs.getProperty("XDG_MUSIC_DIR"); XDG_PICTURES_DIR = userDirs.getProperty("XDG_PICTURES_DIR"); XDG_PUBLICSHARE_DIR = userDirs.getProperty("XDG_PUBLICSHARE_DIR"); XDG_TEMPLATES_DIR = userDirs.getProperty("XDG_TEMPLATES_DIR"); XDG_VIDEOS_DIR = userDirs.getProperty("XDG_VIDEOS_DIR"); } /** * {@link #XDG_DESKTOP_DIR} as a {@link File} object, but only if * {@code XDG_DESKTOP_DIR} is not {@code null} and that * directory actually exists. {@code null} otherwise. */ public static final File XDG_DESKTOP_DIR_FILE = ((XDG_DESKTOP_DIR != null) && new File(XDG_DESKTOP_DIR).isDirectory()) ? new File(XDG_DESKTOP_DIR) : null; /** * {@link #XDG_DOCUMENTS_DIR} as a {@link File} object, but only if * {@code XDG_DOCUMENTS_DIR} is not {@code null} and that * directory actually exists. {@code null} otherwise. */ public static final File XDG_DOCUMENTS_DIR_FILE = ((XDG_DOCUMENTS_DIR != null) && new File(XDG_DOCUMENTS_DIR).isDirectory()) ? new File(XDG_DOCUMENTS_DIR) : null; /** * {@link #XDG_DOWNLOAD_DIR} as a {@link File} object, but only if * {@code XDG_DOWNLOAD_DIR} is not {@code null} and that * directory actually exists. {@code null} otherwise. */ public static final File XDG_DOWNLOAD_DIR_FILE = ((XDG_DOWNLOAD_DIR != null) && new File(XDG_DOWNLOAD_DIR).isDirectory()) ? new File(XDG_DOWNLOAD_DIR) : null; /** * {@link #XDG_MUSIC_DIR} as a {@link File} object, but only if * {@code XDG_MUSIC_DIR} is not {@code null} and that * directory actually exists. {@code null} otherwise. */ public static final File XDG_MUSIC_DIR_FILE = ((XDG_MUSIC_DIR != null) && new File(XDG_MUSIC_DIR).isDirectory()) ? new File(XDG_MUSIC_DIR) : null; /** * {@link #XDG_PICTURES_DIR} as a {@link File} object, but only if * {@code XDG_PICTURES_DIR} is not {@code null} and that * directory actually exists. {@code null} otherwise. */ public static final File XDG_PICTURES_DIR_FILE = ((XDG_PICTURES_DIR != null) && new File(XDG_PICTURES_DIR).isDirectory()) ? new File(XDG_PICTURES_DIR) : null; /** * {@link #XDG_PUBLICSHARE_DIR} as a {@link File} object, but only if * {@code XDG_PUBLICSHARE_DIR} is not {@code null} and that * directory actually exists. {@code null} otherwise. */ public static final File XDG_PUBLICSHARE_DIR_FILE = ((XDG_PUBLICSHARE_DIR != null) && new File(XDG_PUBLICSHARE_DIR).isDirectory()) ? new File(XDG_PUBLICSHARE_DIR) : null; /** * {@link #XDG_TEMPLATES_DIR} as a {@link File} object, but only if * {@code XDG_TEMPLATES_DIR} is not {@code null} and that * directory actually exists. {@code null} otherwise. */ public static final File XDG_TEMPLATES_DIR_FILE = ((XDG_TEMPLATES_DIR != null) && new File(XDG_TEMPLATES_DIR).isDirectory()) ? new File(XDG_TEMPLATES_DIR) : null; /** * {@link #XDG_VIDEOS_DIR} as a {@link File} object, but only if * {@code XDG_VIDEOS_DIR} is not {@code null} and that * directory actually exists. {@code null} otherwise. */ public static final File XDG_VIDEOS_DIR_FILE = ((XDG_VIDEOS_DIR != null) && new File(XDG_VIDEOS_DIR).isDirectory()) ? new File(XDG_VIDEOS_DIR) : null; public static void main(String[] args) { System.out.println("HOME: " + HOME); System.out.println("XDG_DATA_HOME: " + XDG_DATA_HOME); System.out.println("XDG_CONFIG_HOME: " + XDG_CONFIG_HOME); System.out.println("XDG_DATA_DIRS: " + XDG_DATA_DIRS); System.out.println("XDG_CONFIG_DIRS: " + XDG_CONFIG_DIRS); System.out.println("XDG_CACHE_HOME: " + XDG_CACHE_HOME); System.out.println("XDG_RUNTIME_DIR: " + XDG_RUNTIME_DIR); System.out.println("XDG_DATA_HOME_FILE: " + XDG_DATA_HOME_FILE); System.out.println("XDG_CONFIG_HOME_FILE: " + XDG_CONFIG_HOME_FILE); System.out.println("XDG_CACHE_HOME_FILE: " + XDG_CACHE_HOME_FILE); System.out.println("XDG_RUNTIME_DIR_FILE: " + XDG_RUNTIME_DIR_FILE); System.out.println("XDG_DESKTOP_DIR: " + XDG_DESKTOP_DIR); System.out.println("XDG_DOCUMENTS_DIR: " + XDG_DOCUMENTS_DIR); System.out.println("XDG_DOWNLOAD_DIR: " + XDG_DOWNLOAD_DIR); System.out.println("XDG_MUSIC_DIR: " + XDG_MUSIC_DIR); System.out.println("XDG_PICTURES_DIR: " + XDG_PICTURES_DIR); System.out.println("XDG_PUBLICSHARE_DIR: " + XDG_PUBLICSHARE_DIR); System.out.println("XDG_TEMPLATES_DIR: " + XDG_TEMPLATES_DIR); System.out.println("XDG_VIDEOS_DIR: " + XDG_VIDEOS_DIR); System.out.println("XDG_DESKTOP_DIR_FILE: " + XDG_DESKTOP_DIR_FILE); System.out.println("XDG_DOCUMENTS_DIR_FILE: " + XDG_DOCUMENTS_DIR_FILE); System.out.println("XDG_DOWNLOAD_DIR_FILE: " + XDG_DOWNLOAD_DIR_FILE); System.out.println("XDG_MUSIC_DIR_FILE: " + XDG_MUSIC_DIR_FILE); System.out.println("XDG_PICTURES_DIR_FILE: " + XDG_PICTURES_DIR_FILE); System.out.println("XDG_PUBLICSHARE_DIR_FILE: " + XDG_PUBLICSHARE_DIR_FILE); System.out.println("XDG_TEMPLATES_DIR_FILE: " + XDG_TEMPLATES_DIR_FILE); System.out.println("XDG_VIDEOS_DIR_FILE: " + XDG_VIDEOS_DIR_FILE); } private static void readShellVarScript(File script, Properties props) { try { try (BufferedReader in = new BufferedReader(new FileReader(script))) { String line; while ((line = in.readLine()) != null) { line = line.trim(); // Separate the line into key and value int p = line.indexOf('='); if (p < 0) { continue; } String key = line.substring(0, p); String value = line.substring(p + 1); // If the value is surrounded by double quotes, strip them if ((value.length() >= 2) && value.startsWith("\"") && value.endsWith("\"")) { value = value.substring(1, value.length() - 1); } // Expand any variables recursively String previousValue; do { previousValue = value; value = expandVariables(value); } while (!value.equals(previousValue)); // Store the variables as properties props.setProperty(key, value); } } } catch (IOException e) { throw new MDCCapturingRuntimeException("I/O error reading " + script, e); } } private static String expandVariables(String value) { StringBuilder result = new StringBuilder(value.length()); StringBuilder varName = new StringBuilder(100); final int COPYING = 1; final int DOLLAR_ENCOUNTERED = 2; final int READING_VAR_NAME = 3; int state = COPYING; for (int i = 0; i < value.length(); i++) { char c = value.charAt(i); switch (state) { case COPYING: if (c == '$') { state = DOLLAR_ENCOUNTERED; } else { result.append(c); } break; case DOLLAR_ENCOUNTERED: if (Character.isLetter(c) || (c == '_')) { varName.setLength(0); varName.append(c); state = READING_VAR_NAME; } else { result.append('$'); result.append(c); state = COPYING; } break; case READING_VAR_NAME: if (Character.isLetter(c) || Character.isDigit(c) || (c == '_')) { varName.append(c); } else { String varNameStr = varName.toString(); if (varNameStr.equals("HOME")) { result.append(System.getProperty("user.home")); } else if (System.getenv(varNameStr) != null) { result.append(varNameStr); } result.append(c); state = COPYING; } break; } } if (state == DOLLAR_ENCOUNTERED) { result.append('$'); } else if (state == READING_VAR_NAME) { String varNameStr = varName.toString(); if (varNameStr.equals("HOME")) { result.append(System.getProperty("user.home")); } else if (System.getenv(varNameStr) != null) { result.append(varNameStr); } } return result.toString(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy