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

org.freedesktop.dbus.utils.Util Maven / Gradle / Ivy

Go to download

Improved version of the DBus-Java library provided by freedesktop.org (https://dbus.freedesktop.org/doc/dbus-java/).

There is a newer version: 5.1.0
Show newest version
package org.freedesktop.dbus.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Utility class providing helper methods for handling strings, files and so on.
 *
 * @author hypfvieh
 * @since v3.2.5 - 2020-12-28
 */
public final class Util {
    private static final Logger LOGGER = LoggerFactory.getLogger(Util.class);

    /** Characters used for random strings */
    private static final char[] SYMBOLS;

    static {
        StringBuilder tmp = new StringBuilder();
        for (char ch = '0'; ch <= '9'; ++ch) {
          tmp.append(ch);
        }
        for (char ch = 'a'; ch <= 'z'; ++ch) {
          tmp.append(ch);
        }
        for (char ch = 'A'; ch <= 'Z'; ++ch) {
            tmp.append(ch);
        }
        SYMBOLS = tmp.toString().toCharArray();
    }

    private Util() {}

    /**
     * Trys to read a properties file.
     * Returns null if properties file could not be loaded
     * @param _file property file to read
     * @return Properties Object or null
     */
    public static Properties readProperties(File _file) {
        if (_file.exists()) {
            try {
                return readProperties(new FileInputStream(_file));
            } catch (FileNotFoundException _ex) {
                LOGGER.info("Could not load properties file: " + _file, _ex);
            }
        }
        return null;
    }

    /**
     * Tries to read a properties file from an inputstream.
     * @param _stream input stream providing property file content
     * @return properties object/null
     */
    public static Properties readProperties(InputStream _stream) {
        Properties props = new Properties();
        if (_stream == null) {
            return null;
        }

        try {
            props.load(_stream);
            return props;
        } catch (IOException | NumberFormatException _ex) {
            LOGGER.warn("Could not properties: ", _ex);
        }
        return null;
    }

    /**
     * Checks if the given String is either null or blank.
     * Blank means:
*
     * " " - true
     * "" - true
     * null - true
     * " xx" - false
     * 
* @param _str string to test * @return true if string is blank or null, false otherwise */ public static boolean isBlank(String _str) { if (_str == null) { return true; } return _str.isBlank(); } /** * Null-safe equals for two strings. * * @param _str1 first string * @param _str2 second string * @return true if both are equal (also true if both are null) */ public static boolean strEquals(String _str1, String _str2) { if (_str1 == _str2) { return true; } else if (_str1 == null || _str2 == null) { return false; } else if (_str1.length() != _str2.length()) { return false; } return _str1.equals(_str2); } /** * Checks if the given String is either null or empty. * Blank means:
*
     * " " - false
     * "" - true
     * null - true
     * " xx" - false
     * 
* @param _str string to test * @return true if string is empty or null, false otherwise */ public static boolean isEmpty(String _str) { if (_str == null) { return true; } return _str.isEmpty(); } /** * Generate a simple (cryptographic insecure) random string. * @param _length length of random string * @return random string or empty string if _length <= 0 */ public static String randomString(int _length) { if (_length <= 0) { return ""; } Random random = new Random(); char[] buf = new char[_length]; for (int idx = 0; idx < buf.length; ++idx) { buf[idx] = SYMBOLS[random.nextInt(SYMBOLS.length)]; } return new String(buf); } /** * Upper case the first letter of the given string. * * @param _str string * @return uppercased string */ public static String upperCaseFirstChar(String _str) { if (_str == null) { return null; } if (_str.isEmpty()) { return _str; } return _str.substring(0, 1).toUpperCase() + _str.substring(1); } /** * Converts a snake-case-string to camel case string. *
* Eg. this_is_snake_case → thisIsSnakeCase * @param _input string * @return camel case string or input if nothing todo. Returns null if input was null. */ public static String snakeToCamelCase(String _input) { if (isBlank(_input)) { return _input; } Pattern compile = Pattern.compile("_[a-zA-Z]"); Matcher matcher = compile.matcher(_input); String result = _input; while (matcher.find()) { String match = matcher.group(); String replacement = match.replace("_", ""); replacement = replacement.toUpperCase(); result = result.replaceFirst(match, replacement); } return result; } /** * Abbreviates a String using ellipses. * * @param _str string to abbrivate * @param _length max length * @return abbreviated string, original string if string length is lower or equal then desired length or null if input was null */ public static String abbreviate(String _str, int _length) { if (_str == null) { return null; } if (_str.length() <= _length) { return _str; } String abbr = _str.substring(0, _length - 3) + "..."; return abbr; } /** * Check if the given value is a valid network port (1 - 65535). * @param _port 'port' to check * @param _allowWellKnown allow ports below 1024 (aka reserved well known ports) * @return true if int is a valid network port, false otherwise */ public static boolean isValidNetworkPort(int _port, boolean _allowWellKnown) { if (_allowWellKnown) { return _port > 0 && _port < 65536; } return _port > 1024 && _port < 65536; } /** * @see #isValidNetworkPort(int, boolean) * @param _str string to check * @param _allowWellKnown allow well known port * @return true if valid port, false otherwise */ public static boolean isValidNetworkPort(String _str, boolean _allowWellKnown) { if (isInteger(_str, false)) { return isValidNetworkPort(Integer.parseInt(_str), _allowWellKnown); } return false; } /** * Check if string is an either positive or negative integer. * * @param _str string to validate * @param _allowNegative negative integer allowed * @return true if integer, false otherwise */ public static boolean isInteger(String _str, boolean _allowNegative) { if (_str == null) { return false; } String regex = "[0-9]+$"; if (_allowNegative) { regex = "^-?" + regex; } else { regex = "^" + regex; } return _str.matches(regex); } /** * Reads a file to a List<String> (each line is one entry in list). * Line endings (line feed/carriage return) are NOT removed! * * @param _fileName file to read * @return list containing text */ public static List readFileToList(String _fileName) { List localText = getTextfileFromUrl(_fileName, Charset.defaultCharset(), false); return localText; } /** * Reads a file to a String. * Line endings (line feed/carriage return) are NOT removed! * * @param _file file to read * @return String containing content, maybe null */ public static String readFileToString(File _file) { return String.join(System.lineSeparator(), readFileToList(_file.getAbsolutePath())); } /** * Reads a text file from the given URL using the provided charset. * Using the _silent argument optionally disables all error logging. * * @param _url url providing the file to read * @param _charset charset to use * @param _silent true to not log exceptions, false otherwise * @return list of string or null on error */ public static List getTextfileFromUrl(String _url, Charset _charset, boolean _silent) { if (_url == null) { return null; } String fileUrl = _url; if (!fileUrl.contains("://")) { fileUrl = "file://" + fileUrl; } try { URL dlUrl; if (fileUrl.startsWith("file:/")) { dlUrl = new URL("file", "", fileUrl.replaceFirst("file:\\/{1,2}", "")); } else { dlUrl = new URL(fileUrl); } URLConnection urlConn = dlUrl.openConnection(); urlConn.setDoInput(true); urlConn.setUseCaches(false); return readTextFileFromStream(urlConn.getInputStream(), _charset, _silent); } catch (IOException _ex) { if (!_silent) { LOGGER.warn("Error while reading file:", _ex); } } return null; } /** * Reads a text file from given {@link InputStream} using the given {@link Charset}. * @param _input stream to read * @param _charset charset to use * @param _silent true to disable exception logging, false otherwise * @return List of string or null on error */ public static List readTextFileFromStream(InputStream _input, Charset _charset, boolean _silent) { if (_input == null) { return null; } try { List fileContent; try (BufferedReader dis = new BufferedReader(new InputStreamReader(_input, _charset))) { String s; fileContent = new ArrayList<>(); while ((s = dis.readLine()) != null) { fileContent.add(s); } } return !fileContent.isEmpty() ? fileContent : null; } catch (IOException _ex) { if (!_silent) { LOGGER.warn("Error while reading file:", _ex); } } return null; } /** * Write String to file with the given charset. * Optionally appends the data to the file. * * @param _fileName the file to write * @param _fileContent the content to write * @param _charset the charset to use * @param _append append content to file, if false file will be overwritten if existing * * @return true on successful write, false otherwise */ public static boolean writeTextFile(String _fileName, String _fileContent, Charset _charset, boolean _append) { if (isBlank(_fileName)) { return false; } String allText = ""; if (_append) { File file = new File(_fileName); if (file.exists()) { allText = readFileToString(file); } } allText += _fileContent; try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(_fileName), _charset)) { writer.write(allText); } catch (IOException _ex) { LOGGER.error("Could not write file to '" + _fileName + "'", _ex); return false; } return true; } /** * Gets the host name of the local machine. * @return host name */ public static String getHostName() { try { return java.net.InetAddress.getLocalHost().getHostName(); } catch (java.net.UnknownHostException _ex) { return null; } } /** * Checks if any of the 'needle' values are found in 'haystack'. * * @param type * @param _haystack collection to check * @param _needles values to find * * @return true if any value found, false if any parameter null or no matching value found */ public static boolean collectionContainsAny(Collection _haystack, Collection _needles) { if (_haystack == null || _needles == null) { return false; } for (T t : _needles) { if (_haystack.contains(t)) { return true; } } return false; } /** * Determines the current logged on user. * @return logged on user */ public static String getCurrentUser() { String[] sysPropParms = new String[] {"user.name", "USER", "USERNAME"}; for (int i = 0; i < sysPropParms.length; i++) { String val = System.getProperty(sysPropParms[i]); if (!isEmpty(val)) { return val; } } return null; } /** * Checks if the running OS is a MacOS/MacOS X. * @return true if MacOS (or MacOS X), false otherwise */ public static boolean isMacOs() { String osName = System.getProperty("os.name"); return osName != null && osName.toLowerCase(Locale.US).startsWith("mac"); } public static boolean isFreeBsd() { String osName = System.getProperty("os.name"); return osName != null && osName.toLowerCase(Locale.US).startsWith("freebsd"); } /** * Checks if the running OS is a MS Windows OS. * @return true if Windows, false otherwise */ public static boolean isWindows() { String osName = System.getProperty("os.name"); return osName != null && osName.toLowerCase(Locale.US).startsWith("windows"); } /** * Get the java version of the current running JRE. * * @return java major */ public static int getJavaVersion() { String version = System.getProperty("java.version"); if (version.startsWith("1.")) { version = version.substring(2, 3); } else { int dot = version.indexOf('.'); if (dot != -1) { version = version.substring(0, dot); } } return Integer.parseInt(version); } /** * Create a random GUID (used for connection addresses). * * @return String */ public static String genGUID() { Random r = new Random(); byte[] buf = new byte[16]; r.nextBytes(buf); return Hexdump.toHex(buf, false); } /** * Creates a unix socket address using. * * @param _listeningSocket true if the address should be used for a listing socket * @param _abstract true to create an abstract socket * * @return address String */ public static String createDynamicSessionAddress(boolean _listeningSocket, boolean _abstract) { String address = "unix:"; String path = new File(System.getProperty("java.io.tmpdir"), "dbus-XXXXXXXXXX").getAbsolutePath(); Random r = new Random(); do { StringBuffer sb = new StringBuffer(); for (int i = 0; i < 10; i++) { sb.append((char) (Math.abs(r.nextInt()) % 26) + 65); } path = path.replaceAll("..........$", sb.toString()); LoggerFactory.getLogger(Util.class).trace("Trying path {}", path); } while (new File(path).exists()); if (_abstract) { address += "abstract=" + path; } else { address += "path=" + path; } if (_listeningSocket) { address += ",listen=true"; } address += ",guid=" + Util.genGUID(); LoggerFactory.getLogger(Util.class).debug("Created Session address: {}", address); return address; } /** * Checks if given value is greater or equal to the given minimum and less or equal to the given maximum. * * @param _check value to check * @param _min minimum allowed value (including) * @param _max maximum allowed value (including) * * @return given value if in range * @throws IllegalArgumentException when given value is out of range * * @since 4.2.0 - 2022-07-13 */ public static int checkIntInRange(int _check, int _min, int _max) { if (_check >= _min && _check <= _max) { return _check; } throw new IllegalArgumentException("Value " + _check + " is out ouf range (< " + _min + " && > " + _max + ")"); } /** * Setup the unix socket file permissions. * User and group can always be set, file permissions are only set on non-windows OSes. * * @param _path path to file which where permissions should be set * @param _fileOwner new owner for the file * @param _fileGroup new group for the file * @param _fileUnixPermissions unix permissions to set on file */ public static void setFilePermissions(Path _path, String _fileOwner, String _fileGroup, Set _fileUnixPermissions) { Objects.requireNonNull(_path, "Path required"); UserPrincipalLookupService userPrincipalLookupService = _path.getFileSystem().getUserPrincipalLookupService(); if (userPrincipalLookupService == null) { LOGGER.error("Unable to set user/group permissions on {}", _path); } if (!Util.isBlank(_fileOwner)) { try { UserPrincipal userPrincipal = userPrincipalLookupService.lookupPrincipalByName(_fileOwner); if (userPrincipal != null) { Files.getFileAttributeView(_path, PosixFileAttributeView.class, LinkOption.NOFOLLOW_LINKS).setOwner(userPrincipal); } } catch (IOException _ex) { LOGGER.error("Could not change owner of {} to {}", _path, _fileOwner, _ex); } } if (!Util.isBlank(_fileGroup)) { try { GroupPrincipal groupPrincipal = userPrincipalLookupService.lookupPrincipalByGroupName(_fileGroup); if (groupPrincipal != null) { Files.getFileAttributeView(_path, PosixFileAttributeView.class, LinkOption.NOFOLLOW_LINKS).setGroup(groupPrincipal); } } catch (IOException _ex) { LOGGER.error("Could not change group of {} to {}", _path, _fileGroup, _ex); } } if (!Util.isWindows() && _fileUnixPermissions != null) { try { Files.setPosixFilePermissions(_path, _fileUnixPermissions); } catch (Exception _ex) { LOGGER.error("Could not set file permissions of {} to {}", _path, _fileUnixPermissions, _ex); } } } /** * Waits for the provided supplier to return true or throws an exception. *

* This method will call the provided supplier every _sleepTime milliseconds to check * if the supplier returns true.
* If supplier returns true, method will return. * If no value is present after the defined _timeoutMs a {@link IllegalStateException} is thrown. * * @param _lockName name for the lock (used in exception text and logging) * @param _wait supplier to wait for * @param _timeoutMs timeout in milliseconds when wait will fail * @param _sleepTime sleep time between each retries * * @param exception type which might be thrown * * @throws T when timeout is reached */ @SuppressWarnings("unchecked") public static void waitFor(String _lockName, IThrowingSupplier _wait, long _timeoutMs, long _sleepTime) throws T { long waited = 0; boolean wait = false; T lastEx = null; do { try { lastEx = null; // supplier may throw, if so assume that we should still wait and retry wait = _wait.get(); } catch (Throwable _ex) { lastEx = (T) _ex; wait = false; } if (waited >= _timeoutMs) { if (lastEx != null) { // we have a timeout and last retry has thrown a exception throw lastEx; } // we have a timeout and no exception happened before throw new IllegalStateException(_lockName + " not available in the specified time of " + _timeoutMs + " ms"); } try { Thread.sleep(_sleepTime); } catch (InterruptedException _ex) { LOGGER.debug("Interrupted while waiting for {}", _lockName); break; } waited += _sleepTime; LOGGER.debug("Waiting for {} to be available: {} of {} ms waited", _lockName, waited, _timeoutMs); } while (!wait); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy