PageRenderTime 51ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/biz.aQute.bndlib/src/aQute/bnd/osgi/OSInformation.java

https://github.com/brampouwelse/bnd
Java | 368 lines | 294 code | 46 blank | 28 comment | 74 complexity | 4602b8493e3f50762625533002449ad9 MD5 | raw file
Possible License(s): Apache-2.0, EPL-1.0
  1. package aQute.bnd.osgi;
  2. import java.util.ArrayList;
  3. import java.util.Arrays;
  4. import java.util.List;
  5. import java.util.Locale;
  6. import java.util.regex.Matcher;
  7. import java.util.regex.Pattern;
  8. import org.osgi.resource.Capability;
  9. import aQute.bnd.osgi.resource.CapabilityBuilder;
  10. import aQute.bnd.osgi.resource.ResourceUtils;
  11. import aQute.bnd.version.MavenVersion;
  12. import aQute.bnd.version.Version;
  13. import aQute.lib.strings.Strings;
  14. /**
  15. * OS specific information, used by the native_capability macro for
  16. * osgi.native.* bundle properties.
  17. */
  18. public class OSInformation {
  19. String osnames = null;
  20. Version osversion = null;
  21. static private String regexQualifierNotAllowedChars = "[^\\p{Alnum}-_]";
  22. static private Pattern digitPattern = Pattern.compile("(\\d+).*");
  23. final static String[][] processorFamilies = {
  24. new String[] {
  25. "x86-64", "amd64", "em64t", "x86_64"
  26. }, new String[] {
  27. "x86", "pentium", "i386", "i486", "i586", "i686"
  28. }, new String[] {
  29. "68k"
  30. }, new String[] {
  31. "ARM"
  32. }, new String[] {
  33. "ARM_be"
  34. }, new String[] {
  35. "ARM_le"
  36. }, new String[] {
  37. "Alpha"
  38. }, new String[] {
  39. "ia64n"
  40. }, new String[] {
  41. "ia64w"
  42. }, new String[] {
  43. "Ignite", "psc1k"
  44. }, new String[] {
  45. "Mips"
  46. }, new String[] {
  47. "PARisc"
  48. }, new String[] {
  49. "PowerPC", "power", "ppc"
  50. }, new String[] {
  51. "Sh4"
  52. }, new String[] {
  53. "Sparc"
  54. }, new String[] {
  55. "Sparcv9"
  56. }, new String[] {
  57. "S390"
  58. }, new String[] {
  59. "V850e"
  60. },
  61. };
  62. static String[] osarch = getProcessorAliases(System.getProperty("os.arch"));
  63. public static String[] getProcessorAliases(String osArch) {
  64. for (String[] pnames : processorFamilies) {
  65. for (String pname : pnames)
  66. if (pname.equalsIgnoreCase(osArch))
  67. return pnames;
  68. }
  69. return null;
  70. }
  71. public static String[] getProcessorAliases() {
  72. return osarch;
  73. }
  74. /**
  75. * <p>
  76. * Convert a generic Unix kernel version to an OSGi version.
  77. * </p>
  78. * <p>
  79. * As long as we have digits separated by dots, convert the digits into the
  80. * respective version segments. Anything left after that conversion is the
  81. * qualifier. Illegal characters in that qualifier are converted into
  82. * underscores to ensure that the final qualifier is valid.
  83. * </p>
  84. *
  85. * @param sysPropOsVersion the system property "os.version"
  86. */
  87. static Version convertUnixKernelVersion(String sysPropOsVersion) {
  88. Version osversion = new Version(0, 0, 0);
  89. String s = sysPropOsVersion.trim();
  90. int index = 0;
  91. do {
  92. Matcher matcher = digitPattern.matcher(s);
  93. if (matcher.matches()) {
  94. String matchedDigit = matcher.group(1);
  95. int matchedDigitNumber;
  96. try {
  97. matchedDigitNumber = Integer.parseInt(matchedDigit);
  98. } catch (NumberFormatException e) {
  99. assert (false);
  100. break;
  101. }
  102. switch (index) {
  103. case 0 :
  104. osversion = new Version(matchedDigitNumber, osversion.getMinor(), osversion.getMicro());
  105. break;
  106. case 1 :
  107. osversion = new Version(osversion.getMajor(), matchedDigitNumber, osversion.getMicro());
  108. break;
  109. case 2 :
  110. osversion = new Version(osversion.getMajor(), osversion.getMinor(), matchedDigitNumber);
  111. break;
  112. default :
  113. assert (false);
  114. break;
  115. }
  116. s = s.substring(matchedDigit.length());
  117. if (s.length() == 0 || s.charAt(0) != '.') {
  118. break;
  119. }
  120. s = s.substring(1);
  121. index++;
  122. }
  123. } while (index < 3);
  124. if (s.length() != 0) {
  125. String qualifier = s.replaceAll(regexQualifierNotAllowedChars, "_");
  126. osversion = new Version(osversion.getMajor(), osversion.getMinor(), osversion.getMicro(), qualifier);
  127. }
  128. return osversion;
  129. }
  130. /**
  131. * Construct OS specific information
  132. *
  133. * @throws IllegalArgumentException
  134. */
  135. public OSInformation() throws IllegalArgumentException {
  136. this(System.getProperty("os.name"), System.getProperty("os.version"));
  137. }
  138. public OSInformation(String sysPropOsName, String sysPropOsVersion) throws IllegalArgumentException {
  139. if (sysPropOsName == null || sysPropOsName.length() == 0 || sysPropOsVersion == null
  140. || sysPropOsVersion.length() == 0) {
  141. return;
  142. }
  143. OSNameVersion pair = getOperatingSystemAliases(sysPropOsName, sysPropOsVersion);
  144. if (pair == null)
  145. throw new IllegalArgumentException(
  146. "Unknown OS/version combination: " + sysPropOsName + " " + sysPropOsVersion);
  147. osversion = pair.osversion;
  148. osnames = pair.osnames;
  149. }
  150. static class NativeCapability {
  151. public List<String> processor = new ArrayList<>();
  152. public List<String> osname = new ArrayList<>();
  153. public Version osversion;
  154. public String language = "en";
  155. }
  156. /**
  157. * Helper for the Processor._native_capability macro
  158. *
  159. * @param args the arguments of the macro
  160. * @return a provide capability clause for the native environment
  161. */
  162. public static String getNativeCapabilityClause(Processor p, String args[]) throws Exception {
  163. NativeCapability clause = new NativeCapability();
  164. parseNativeCapabilityArgs(p, args, clause);
  165. validateNativeCapability(clause);
  166. Capability cap = createCapability(clause);
  167. return ResourceUtils.toProvideCapability(cap);
  168. }
  169. static Capability createCapability(NativeCapability clause) throws Exception {
  170. CapabilityBuilder c = new CapabilityBuilder("osgi.native");
  171. c.addAttribute("osgi.native.osname", clause.osname);
  172. c.addAttribute("osgi.native.osversion", clause.osversion);
  173. c.addAttribute("osgi.native.processor", clause.processor);
  174. c.addAttribute("osgi.native.language", clause.language);
  175. Capability cap = c.synthetic();
  176. return cap;
  177. }
  178. static void validateNativeCapability(NativeCapability clause) {
  179. if (clause.osversion == null)
  180. throw new IllegalArgumentException("osversion/osgi.native.osversion not set in ${native_capability}");
  181. if (clause.osname.isEmpty())
  182. throw new IllegalArgumentException("osname/osgi.native.osname not set in ${native_capability}");
  183. if (clause.processor.isEmpty())
  184. throw new IllegalArgumentException("processor/osgi.native.processor not set in ${native_capability}");
  185. }
  186. static void parseNativeCapabilityArgs(Processor p, String[] args, NativeCapability clause) throws Exception {
  187. if (args.length == 1) {
  188. OSInformation osi = new OSInformation();
  189. clause.osname.addAll(Strings.split(osi.osnames));
  190. clause.osversion = osi.osversion;
  191. clause.processor.addAll(Arrays.asList(getProcessorAliases(System.getProperty("os.arch"))));
  192. clause.language = Locale.getDefault()
  193. .toString();
  194. StringBuilder sb = new StringBuilder();
  195. sb.append("osname=")
  196. .append(System.getProperty("os.name"));
  197. sb.append(";")
  198. .append("osversion=")
  199. .append(MavenVersion.cleanupVersion(System.getProperty("os.version")));
  200. sb.append(";")
  201. .append("processor=")
  202. .append(System.getProperty("os.arch"));
  203. sb.append(";")
  204. .append("lang=")
  205. .append(clause.language);
  206. String advice = sb.toString();
  207. } else {
  208. String osname = null;
  209. for (int i = 1; i < args.length; i++) {
  210. String parts[] = args[i].split("\\s*=\\s*");
  211. if (parts.length != 2)
  212. throw new IllegalArgumentException(
  213. "Illegal property syntax in \"" + args[i] + "\", use \"key=value\"");
  214. String key = Strings.trim(parts[0]);
  215. String value = Strings.trim(parts[1]);
  216. boolean isList = value.indexOf(',') > 0;
  217. switch (key) {
  218. case "processor" :
  219. case "osgi.native.processor" :
  220. if (isList)
  221. clause.processor.addAll(Strings.split(value));
  222. else {
  223. if ("arm".equals(value)) {
  224. p.warning("The 'arm' processor is deprecated. Specify either 'arm_le' or 'arm_be'");
  225. }
  226. String[] processorAliases = getProcessorAliases(value);
  227. if (processorAliases != null && processorAliases.length > 0) {
  228. clause.processor.addAll(Arrays.asList(processorAliases));
  229. } else {
  230. clause.processor.add(value);
  231. }
  232. }
  233. break;
  234. case "osname" :
  235. case "osgi.native.osname" :
  236. if (isList)
  237. clause.osname.addAll(Strings.split(value));
  238. else {
  239. if (osname == null) {
  240. osname = value;
  241. } else {
  242. clause.osname.add(osname);
  243. osname = value;
  244. }
  245. }
  246. break;
  247. case "osversion" :
  248. case "osgi.native.osversion" :
  249. if (clause.osversion == null) {
  250. clause.osversion = Version.parseVersion(value);
  251. } else
  252. throw new IllegalArgumentException(
  253. "osversion/osgi.native.osversion can only be set once in ${native_capability}");
  254. break;
  255. case "osgi.native.language" :
  256. case "lang" :
  257. if (clause.language != null)
  258. throw new IllegalArgumentException(
  259. "lang/osgi.native.lang can only be set once in ${native_capability}");
  260. clause.language = value;
  261. break;
  262. }
  263. }
  264. if (osname != null) {
  265. try {
  266. OSInformation osi = new OSInformation(osname, clause.osversion.toString());
  267. clause.osname.addAll(Strings.split(osi.osnames));
  268. } catch (Exception e) {
  269. clause.osname.add(osname);
  270. }
  271. }
  272. }
  273. }
  274. public static class OSNameVersion {
  275. public Version osversion;
  276. public String osnames;
  277. }
  278. public static OSNameVersion getOperatingSystemAliases(String sysPropOsName, String sysPropOsVersion) {
  279. OSNameVersion nc = new OSNameVersion();
  280. if (sysPropOsName.startsWith("Windows")) {
  281. if (sysPropOsVersion.startsWith("10.0")) {
  282. nc.osversion = new Version(10, 0, 0);
  283. nc.osnames = "Windows10,Windows 10,Win32";
  284. } else if (sysPropOsVersion.startsWith("6.3")) {
  285. nc.osversion = new Version(6, 3, 0);
  286. nc.osnames = "Windows8.1,Windows 8.1,Win32";
  287. } else if (sysPropOsVersion.startsWith("6.2")) {
  288. nc.osversion = new Version(6, 2, 0);
  289. nc.osnames = "Windows8,Windows 8,Win32";
  290. } else if (sysPropOsVersion.startsWith("6.1")) {
  291. nc.osversion = new Version(6, 1, 0);
  292. nc.osnames = "Windows7,Windows 7,Win32";
  293. } else if (sysPropOsVersion.startsWith("6.0")) {
  294. nc.osversion = new Version(6, 0, 0);
  295. nc.osnames = "WindowsVista,WinVista,Windows Vista,Win32";
  296. } else if (sysPropOsVersion.startsWith("5.1")) {
  297. nc.osversion = new Version(5, 1, 0);
  298. nc.osnames = "WindowsXP,WinXP,Windows XP,Win32";
  299. } else {
  300. nc = null;
  301. }
  302. } else if (sysPropOsName.startsWith("Mac OS X")) {
  303. nc.osversion = convertUnixKernelVersion(sysPropOsVersion);
  304. nc.osnames = "MacOSX,Mac OS X";
  305. return nc;
  306. } else if (sysPropOsName.toLowerCase()
  307. .startsWith("linux")) {
  308. nc.osversion = convertUnixKernelVersion(sysPropOsVersion);
  309. nc.osnames = "Linux";
  310. } else if (sysPropOsName.startsWith("Solaris")) {
  311. nc.osversion = convertUnixKernelVersion(sysPropOsVersion);
  312. nc.osnames = "Solaris";
  313. } else if (sysPropOsName.startsWith("AIX")) {
  314. nc.osversion = convertUnixKernelVersion(sysPropOsVersion);
  315. nc.osnames = "AIX";
  316. } else if (sysPropOsName.startsWith("HP-UX")) {
  317. nc.osversion = convertUnixKernelVersion(sysPropOsVersion);
  318. nc.osnames = "HPUX,hp-ux";
  319. }
  320. return nc;
  321. }
  322. }