/* * Copyright (C) 2009-2017 Alistair Neil * * 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 2 * 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, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package lib; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.lang.management.ManagementFactory; import java.lang.management.RuntimeMXBean; import java.util.ArrayList; import java.util.Locale; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * * @author Alistair Neil */ public class OSFunction { private static ArrayList alProcesses; /** * Get process id * * @return Process id or -1 if not found */ public static String getOurProcessID() { RuntimeMXBean rtb = ManagementFactory.getRuntimeMXBean(); String processName = rtb.getName(); Integer pid = tryPattern(processName); return String.valueOf(pid); } /** * Get process id from a process * * @param process * @return process id as String */ public static String getProcessID(String process) { Pattern pattern = Pattern.compile(" +"); String[] result = pattern.split(process.trim()); if (isWindows()) { return result[1]; } else { return result[0]; } } private static Integer tryPattern(String processName) { Integer result = null; Pattern pattern = Pattern.compile("^([0-9]+)@.+$", Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(processName); if (matcher.matches()) { result = Integer.parseInt(matcher.group(1)); } return result; } /** * Get OS version * * @return String OS version */ public static String getOSVersion() { return System.getProperty("os.version"); } /** * Get user name * * @return String User name */ public static String getUserName() { return System.getProperty("user.name"); } /** * Get users home folder * * @return String path to home folder */ public static String getUsersHomeFolder() { return System.getProperty("user.home"); } /** * Get file separator * * @return String separator */ public static String getFileSeparator() { return System.getProperty("file.separator"); } /** * Get users documents folder (Windows only) * * @return String path to documents folder */ public static String getUsersDocFolder() { String strReturn = getUsersHomeFolder() + "\\Documents"; if (isWinXP()) { strReturn = getUsersHomeFolder() + "\\My Documents"; } return strReturn; } /** * Get user settings path * * @return String path to user settings folder */ public static String getUserSettingsPath() { String userSettingsPath; if (isWindows()) { userSettingsPath = getUsersHomeFolder() + "\\Application Data\\"; } else { userSettingsPath = getUsersHomeFolder() + "/"; } return userSettingsPath; } /** * Get a specified application's settings folder, if null return this * applications setting folder * * @param appname Application settings folder name * @param appseries Application series (optional) * @return String Path to the applications setting folder */ public static String getAppSettingsPath(String appname, String appseries) { String appSettingsPath = getUserSettingsPath(); if (appname == null) { return appSettingsPath; } if (isLinux()) { appname = "." + appname; } appSettingsPath += appname + getFileSeparator(); if (appseries != null) { appSettingsPath += appseries + getFileSeparator(); } return appSettingsPath; } /** * Get users current folder * * @return String Path to current folder */ public static String getUsersCurrentFolder() { return System.getProperty("user.dir"); } /** * Get users temp folder * * @param path * @return String Path to users temp folder */ public static String getTempFolder(String path) { String result = System.getProperty("java.io.tmpdir"); String sep = ""; if (isLinux()) { sep = getFileSeparator(); } result += sep; if (path != null && !path.isEmpty()) { if (isWindows()) { sep = getFileSeparator(); } result = result + path + sep; } return result; } /** * Get OS name, convenience method * * @return String */ public static String getOSName() { return System.getProperty("os.name").toLowerCase(); } /** * Get OS architecture, convenience method * * @return String */ public static String getOSArch() { return System.getProperty("os.arch"); } /** * Generic test for Windows platform * * @return boolean True if Windows */ public static boolean isWindows() { return getOSName().contains("windows"); } /** * Specific test for Win 7 * * @return boolean True if Win 7 */ public static boolean isWin7() { return getOSName().startsWith("windows 7"); } /** * Specific test for Win 8 * * @return boolean True if Win 8 */ public static boolean isWin8() { return getOSName().startsWith("windows 8"); } /** * Specific test for Win 10 * * @return boolean True if Win 10 */ public static boolean isWin10() { return getOSName().startsWith("windows 10"); } /** * Specific test for Win XP * * @return boolean True if Win XP */ public static boolean isWinXP() { return getOSName().contentEquals("windows"); } /** * Generic test for Linux platform * * @return boolean True if Linux */ public static boolean isLinux() { return getOSName().contains("linux"); } /** * Find a specific file, requires a series of paths where it might be found * to be provided * * @param fname * @param paths * @return String path to file or null */ public static String findFile(String fname, String... paths) { for (String s : paths) { if (new File(s + fname).exists()) { return s + fname; } } return null; } /** * Test to see if their are multiple instances of the this app running * * @param appname * @return True if multiple instance */ public static boolean isMultipleInstance(String appname) { if (alProcesses == null) { alProcesses = getLiveProcesses(); } ArrayList processes = OSFunction.filterProcesses(appname); return OSFunction.filterProcesses(processes, "java").size() > 1; } /** * Cached list of processes * * @return list */ public static ArrayList getCachedProcesses() { return alProcesses; } /** * Find processes matching the contents of filter * * @param processes * @param filter * @return ArrayList of matching processes */ public static ArrayList filterProcesses(ArrayList processes, String filter) { ArrayList result = new ArrayList<>(); if (processes != null && !processes.isEmpty()) { if (filter != null) { for (String s : processes) { if (s.contains(filter)) { result.add(s); } } } } return result; } /** * Find processes matching the contents of filter * * @param filter * @return ArrayList of matching processes */ public static ArrayList filterProcesses(String filter) { ArrayList result = new ArrayList<>(); if (!alProcesses.isEmpty()) { if (filter != null) { for (String s : alProcesses) { if (s.contains(filter)) { result.add(s); } } } } return result; } /** * Generic kill process with matching pid * * @param pid * @return String kill result or null if failed */ public static String killProcess(String pid) { if (isWindows()) { return killProcessWindows(pid); } if (isLinux()) { return killProcessLinux(pid); } return null; } /** * Windows specific kill process with matching pid * * @param pid * @return String kill result or null if failed */ private static String killProcessWindows(String pid) { Process processKill; try { processKill = Runtime.getRuntime().exec("taskkill /F /pid " + pid); return getProcessResult(processKill); } catch (IOException ex) { Logger.getGlobal().logp(Level.WARNING, OSFunction.class.getName(), "killProcessWindows", "", ex); } try { processKill = Runtime.getRuntime().exec("tskill " + pid); return getProcessResult(processKill); } catch (IOException ex) { Logger.getGlobal().logp(Level.WARNING, OSFunction.class.getName(), "killProcessWindows", "", ex); } return null; } /** * Linux specific specific kill process with matching pid * * @param pid * @return String kill result or null if failed */ private static String killProcessLinux(String pid) { Process processKill = null; try { processKill = Runtime.getRuntime().exec("kill -9 " + pid); } catch (IOException ex) { Logger.getGlobal().logp(Level.WARNING, OSFunction.class.getName(), "killProcessLinux", "", ex); } return getProcessResult(processKill); } /** * Set a files hidden status (Windows only) * * @param filepath Path to file includes filename * @param hidden True/False */ public static void setFileHidden(String filepath, boolean hidden) { if (isWindows()) { try { if (hidden) { Runtime.getRuntime().exec("Attrib.exe +H " + filepath).waitFor(); } else { Runtime.getRuntime().exec("Attrib.exe -H " + filepath).waitFor(); } } catch (IOException | InterruptedException ex) { Logger.getGlobal().logp(Level.WARNING, OSFunction.class.getName(), "setFileHidden", "", ex); } } } /** * Get gnome 3 preference using schema name and key name * * @param schema * @param key * @return String preference value */ public static String getGnome3Pref(String schema, String key) { Process p = launchProcess("gsettings", "get", schema, key); String result = getProcessResult(p); if (result != null) { result = result.replace("'", "").replace("[", "").replace("]", ""); } return result; } /** * Set a gnome 3 boolean value using schema name and key name * * @param schema * @param key * @param value */ public static void setGnome3Pref(String schema, String key, boolean value) { setGnome3Pref(schema, key, String.valueOf(value)); } /** * Set a gnome 3 string value using schema name and key name * * @param schema * @param key * @param value */ public static void setGnome3Pref(String schema, String key, String value) { if (value == null || value.isEmpty()) { resetGnome3Pref(schema, key); } else { launchProcess("gsettings", "set", schema, key, "'" + value + "'"); } } /** * Reset a gnome3 value to its default. If key is null, it will reset the * whole schema tree to its defaults * * @param schema * @param key */ public static void resetGnome3Pref(String schema, String key) { if (key == null) { launchProcess("gsettings", "reset", schema); } else { launchProcess("gsettings", "reset", schema, key); } } /** * Get a kde preference string value using group name, key name and return * contents of def on failure * * @param group * @param key * @param def * @return String Preference value */ public static String getKDEPref(String group, String key, String def) { // If exists read the file contents and find the matching key String strKdePath = getKDEProxyPath(); if (strKdePath == null) { return null; } String strTemp = null; SimpleFile sf = new SimpleFile(strKdePath); sf.openBufferedRead(); while ((strTemp = sf.readLine()) != null) { if (strTemp.contains("[" + group + "]")) { break; } } if (strTemp == null) { return def; } while ((strTemp = sf.readLine()) != null) { if (strTemp.contains(key)) { break; } } sf.closeFile(); if (strTemp == null) { return def; } strTemp = strTemp.substring(strTemp.indexOf('=') + 1); return strTemp; } /** * Set a kde string preference value using group name, key name * * @param group * @param key * @param value */ public static void setKDEPref(String group, String key, String value) { // If exists read the file contents and find the matching key String strKdePath = getKDEProxyPath(); if (strKdePath == null) { return; } SimpleFile sf = new SimpleFile(strKdePath); // Get file contents into a array list for further processing String strTemp; ArrayList listContents = new ArrayList<>(); sf.openBufferedRead(); while ((strTemp = sf.readLine()) != null) { listContents.add(strTemp); } sf.closeFile(); // Process contents of file and write it back out sf.openBufferedWrite(); // Find Group entry boolean entryfound = false; while (!listContents.isEmpty()) { strTemp = listContents.get(0); sf.writeFile(strTemp, 1); listContents.remove(0); if (strTemp.contentEquals("[" + group + "]")) { entryfound = true; break; } } // If no group entry found then write one if (!entryfound) { sf.writeFile("", 1); sf.writeFile("[" + group + "]", 1); } // Find key entry while (!listContents.isEmpty()) { strTemp = listContents.get(0); listContents.remove(0); if (strTemp.contains(key)) { break; } sf.writeFile(strTemp, 1); } sf.writeFile(key + "=" + value, 1); // Write out rest of file while (!listContents.isEmpty()) { strTemp = listContents.get(0); listContents.remove(0); sf.writeFile(strTemp, 1); } sf.closeFile(); } /** * Set a kde boolean preference value using group name, key name * * @param group * @param key * @param value */ public static void setKDEPref(String group, String key, boolean value) { setKDEPref(group, key, String.valueOf(value)); } /** * Set a kde integer preference value using group name, key name * * @param group * @param key * @param value */ public static void setKDEPref(String group, String key, int value) { setKDEPref(group, key, String.valueOf(value)); } /** * Test for KDE installed (Linux only) * * @return String path to kde proxy file or null */ public static String getKDEProxyPath() { if (isLinux()) { File f = new File(getUsersHomeFolder() + "/.config/kioslaverc"); if (f.exists()) { return f.getAbsolutePath(); } f = new File(getUsersHomeFolder() + "/.kde/share/config/kioslaverc"); if (f.exists()) { return f.getAbsolutePath(); } f = new File(getUsersHomeFolder() + "/.kde4/share/config/kioslaverc"); if (f.exists()) { return f.getAbsolutePath(); } } return null; } /** * Test if gsettings installed (Linux only) * * @return String path to gsetttings */ public static String getGsettingsPath() { // Verify if gsettings is installed return findFile("gsettings", "/usr/bin/"); } /** * Convenience method to get the first resultant output of an executed * process as a String * * @param aprocess * @return String Process result */ public static String getProcessResult(Process aprocess) { if (aprocess == null) { return null; } return getProcessOutput(aprocess.getInputStream()).toString(); } /** * Obtain all output of an executed process. * * @param is * @return ArrayList of Strings containing all generated output */ public static ArrayList getProcessOutput(InputStream is) { String line; ArrayList arrList = new ArrayList<>(); try { try (BufferedReader input = new BufferedReader(new InputStreamReader(is))) { while ((line = input.readLine()) != null) { if (line.isEmpty()) { continue; } arrList.add(line); } } return arrList; } catch (IOException ex) { Logger.getGlobal().logp(Level.SEVERE, OSFunction.class.getName(), "getProcessResults", "", ex); } return null; } /** * Launch an external process with arguments * * @param command * @return Process */ public static Process launchProcess(String... command) { try { Process p = Runtime.getRuntime().exec(command); if (p == null) { Logger.getGlobal().logp(Level.WARNING, OSFunction.class.getName(), "launchProcess", "Failed Process", ""); } return p; } catch (IOException ex) { Logger.getGlobal().logp(Level.WARNING, OSFunction.class.getName(), "launchProcess", "", ex); } return null; } /** * Gets list of active system processes * * @return Arraylist of system process */ public static ArrayList getLiveProcesses() { if (isWindows()) { return getActiveProcessesWindows(); } else { return getActiveProcessesLinux(); } } /** * Windows specific refresh or internal list of active system processes */ private static ArrayList getActiveProcessesWindows() { ArrayList alResult = new ArrayList<>(); try { Logger.getGlobal().info("refreshActiveProcessesWindows()"); Process p = Runtime.getRuntime().exec(System.getenv("windir") + "\\system32\\" + "tasklist.exe /v"); alResult = getProcessOutput(p.getInputStream()); if (alResult.size() > 1) { // Remove second entry alResult.remove(1); } return alResult; } catch (IOException ex) { Logger.getGlobal().logp(Level.WARNING, OSFunction.class.getName(), "refreshActiveProcessesWindows", "", ex); } return alResult; } /** * Linux specific refresh or internal list of active system processes */ private static ArrayList getActiveProcessesLinux() { ArrayList alResult = new ArrayList<>(); try { Process process = Runtime.getRuntime().exec("ps ax"); alResult = getProcessOutput(process.getInputStream()); return alResult; } catch (IOException ex) { Logger.getGlobal().logp(Level.WARNING, OSFunction.class.getName(), "refreshActiveProcessesLinux", "", ex); } return alResult; } /** * Get the name of the compositor * * @return name as String */ public static String getCompositor() { String result = "unknown"; if (isWin7() || isWin8() || isWin10()) { return "DWM"; } if (isWindows()) { return getOSName(); } if (alProcesses == null) { alProcesses = getLiveProcesses(); } for (String s : alProcesses) { if (s.contains("kwin")) { result = "kwin"; break; } if (s.contains("compton")) { result = "compton"; break; } if (s.contains("cinnamon")) { result = "clutter"; break; } if (s.contains("marco")) { result = "marco"; break; } if (s.contains("compiz")) { result = "compiz"; break; } } return result; } /** * Get the name of the active desktop * * @return name as String */ public static String getActiveDesktop() { if (isWindows()) { return getOSName(); } String result = "unknown"; if (alProcesses == null) { alProcesses = getLiveProcesses(); } for (String s : alProcesses) { if (s.contains("cinnamon-session")) { result = "cinnamon"; break; } if (s.contains("xfce4-session")) { result = "xfce"; break; } if (s.contains("mate-session")) { result = "mate"; break; } if (s.contains("gnome-shell")) { result = "gnome3"; break; } if (s.contains("unity-settings-daemon")) { result = "unity"; break; } if (s.contains("lxsession")) { result = "lxde"; break; } if (s.contains("plasma-desktop")) { result = "kde4"; break; } if (s.contains("plasmashell")) { result = "kde5"; break; } if (s.contains("enlightenment")) { result = "enlightenment"; break; } } return result; } /** * Clear active processes, mainly to reduce memory consumption when were * done with them */ public static void clearActiveProcesses() { alProcesses.clear(); alProcesses = null; } /** * Get default language iso code * * @return language iso code */ public static String getLangCode() { return Locale.getDefault().getLanguage(); } }