1
2
3
4
5 package oshi.software.os.linux;
6
7 import oshi.software.os.ApplicationInfo;
8 import oshi.util.ExecutingCommand;
9 import oshi.util.ParseUtil;
10
11 import java.util.ArrayList;
12 import java.util.Collections;
13 import java.util.HashMap;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.LinkedHashSet;
17 import java.util.LinkedHashMap;
18 import java.util.Set;
19 import java.util.regex.Pattern;
20
21 public final class LinuxInstalledApps {
22
23 private static final Pattern PIPE_PATTERN = Pattern.compile("\\|");
24 private static final Map<String, String> PACKAGE_MANAGER_COMMANDS = initializePackageManagerCommands();
25
26 private LinuxInstalledApps() {
27 }
28
29 private static Map<String, String> initializePackageManagerCommands() {
30 Map<String, String> commands = new HashMap<>();
31
32 if (isPackageManagerAvailable("dpkg")) {
33 commands.put("dpkg",
34 "dpkg-query -W -f=${Package}|${Version}|${Architecture}|${Installed-Size}|${db-fsys:Last-Modified}|${Maintainer}|${Source}|${Homepage}\\n");
35 } else if (isPackageManagerAvailable("rpm")) {
36 commands.put("rpm",
37 "rpm -qa --queryformat %{NAME}|%{VERSION}-%{RELEASE}|%{ARCH}|%{SIZE}|%{INSTALLTIME}|%{PACKAGER}|%{SOURCERPM}|%{URL}\\n");
38 }
39
40 return commands;
41 }
42
43
44
45
46
47
48
49 public static List<ApplicationInfo> queryInstalledApps() {
50 List<String> output = fetchInstalledApps();
51 return parseLinuxAppInfo(output);
52 }
53
54
55
56
57
58
59
60
61
62 private static List<String> fetchInstalledApps() {
63 if (PACKAGE_MANAGER_COMMANDS.isEmpty()) {
64 return Collections.emptyList();
65 }
66
67
68 String command = PACKAGE_MANAGER_COMMANDS.values().iterator().next();
69 return ExecutingCommand.runNative(command);
70 }
71
72 private static boolean isPackageManagerAvailable(String packageManager) {
73 List<String> result = ExecutingCommand.runNative(packageManager + " --version");
74
75 return !result.isEmpty();
76 }
77
78 private static List<ApplicationInfo> parseLinuxAppInfo(List<String> output) {
79 Set<ApplicationInfo> appInfoSet = new LinkedHashSet<>();
80
81 for (String line : output) {
82
83 String[] parts = PIPE_PATTERN.split(line, -1);
84
85
86 if (parts.length >= 8) {
87
88 Map<String, String> additionalInfo = new LinkedHashMap<>();
89 additionalInfo.put("architecture", ParseUtil.getStringValueOrUnknown(parts[2]));
90 additionalInfo.put("installedSize", String.valueOf(ParseUtil.parseLongOrDefault(parts[3], 0L)));
91 additionalInfo.put("source", ParseUtil.getStringValueOrUnknown(parts[6]));
92 additionalInfo.put("homepage", ParseUtil.getStringValueOrUnknown(parts[7]));
93
94 ApplicationInfo app = new ApplicationInfo(ParseUtil.getStringValueOrUnknown(parts[0]),
95 ParseUtil.getStringValueOrUnknown(parts[1]),
96 ParseUtil.getStringValueOrUnknown(parts[5]),
97 ParseUtil.parseLongOrDefault(parts[4], 0L),
98 additionalInfo);
99
100 appInfoSet.add(app);
101 }
102 }
103
104 return new ArrayList<>(appInfoSet);
105 }
106 }