aQute.bnd.osgi.OSInformation Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of biz.aQute.bndlib Show documentation
Show all versions of biz.aQute.bndlib Show documentation
bndlib: A Swiss Army Knife for OSGi
package aQute.bnd.osgi;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.osgi.resource.Capability;
import aQute.bnd.osgi.resource.CapabilityBuilder;
import aQute.bnd.osgi.resource.ResourceUtils;
import aQute.bnd.version.MavenVersion;
import aQute.bnd.version.Version;
import aQute.lib.strings.Strings;
/**
* OS specific information, used by the native_capability macro for
* osgi.native.* bundle properties.
*/
public class OSInformation {
String osnames = null;
Version osversion = null;
static private String regexQualifierNotAllowedChars = "[^\\p{Alnum}-_]";
static private Pattern digitPattern = Pattern.compile("(\\d+).*");
final static String[][] processorFamilies = {
new String[] {
"x86-64", "amd64", "em64t", "x86_64"
},
new String[] {
"x86", "pentium", "i386", "i486", "i586", "i686"
},
new String[] {
"68k"
},
new String[] {
"ARM"
},
new String[] {
"ARM_be"
},
new String[] {
"ARM_le"
},
new String[] {
"Alpha"
},
new String[] {
"ia64n"
},
new String[] {
"ia64w"
},
new String[] {
"Ignite", "psc1k"
},
new String[] {
"Mips"
},
new String[] {
"PARisc"
},
new String[] {
"PowerPC", "power", "ppc"
},
new String[] {
"Sh4"
},
new String[] {
"Sparc"
},
new String[] {
"Sparcv9"
},
new String[] {
"S390"
},
new String[] {
"V850e"
},
};
static String[] osarch = getProcessorAliases(System.getProperty("os.arch"));
public static String[] getProcessorAliases(String osArch) {
for (String[] pnames : processorFamilies) {
for (String pname : pnames)
if (pname.equalsIgnoreCase(osArch))
return pnames;
}
return null;
}
public static String[] getProcessorAliases() {
return osarch;
}
/**
*
* Convert a generic Unix kernel version to an OSGi version.
*
*
* As long as we have digits separated by dots, convert the digits into the
* respective version segments. Anything left after that conversion is the
* qualifier. Illegal characters in that qualifier are converted into
* underscores to ensure that the final qualifier is valid.
*
*
* @param sysPropOsVersion the system property "os.version"
*/
static Version convertUnixKernelVersion(String sysPropOsVersion) {
Version osversion = new Version(0, 0, 0);
String s = sysPropOsVersion.trim();
int index = 0;
do {
Matcher matcher = digitPattern.matcher(s);
if (matcher.matches()) {
String matchedDigit = matcher.group(1);
int matchedDigitNumber;
try {
matchedDigitNumber = Integer.parseInt(matchedDigit);
} catch (NumberFormatException e) {
assert(false);
break;
}
switch (index) {
case 0 :
osversion = new Version(matchedDigitNumber, osversion.getMinor(), osversion.getMicro());
break;
case 1 :
osversion = new Version(osversion.getMajor(), matchedDigitNumber, osversion.getMicro());
break;
case 2 :
osversion = new Version(osversion.getMajor(), osversion.getMinor(), matchedDigitNumber);
break;
default :
assert(false);
break;
}
s = s.substring(matchedDigit.length());
if (s.length() == 0 || s.charAt(0) != '.') {
break;
}
s = s.substring(1);
index++;
}
} while (index < 3);
if (s.length() != 0) {
String qualifier = s.replaceAll(regexQualifierNotAllowedChars, "_");
osversion = new Version(osversion.getMajor(), osversion.getMinor(), osversion.getMicro(), qualifier);
}
return osversion;
}
/**
* Construct OS specific information
*
* @throws IllegalArgumentException
*/
public OSInformation() throws IllegalArgumentException {
this(System.getProperty("os.name"), System.getProperty("os.version"));
}
public OSInformation(String sysPropOsName, String sysPropOsVersion) throws IllegalArgumentException {
if (sysPropOsName == null || sysPropOsName.length() == 0 || sysPropOsVersion == null
|| sysPropOsVersion.length() == 0) {
return;
}
OSNameVersion pair = getOperatingSystemAliases(sysPropOsName, sysPropOsVersion);
if (pair == null)
throw new IllegalArgumentException(
"Unknown OS/version combination: " + sysPropOsName + " " + sysPropOsVersion);
osversion = pair.osversion;
osnames = pair.osnames;
}
static class NativeCapability {
public List processor = new ArrayList<>();
public List osname = new ArrayList<>();
public Version osversion;
public String language = "en";
}
/**
* Helper for the Processor._native_capability macro
*
* @param args the arguments of the macro
* @return a provide capability clause for the native environment
*/
public static String getNativeCapabilityClause(Processor p, String args[]) throws Exception {
NativeCapability clause = new NativeCapability();
parseNativeCapabilityArgs(p, args, clause);
validateNativeCapability(clause);
Capability cap = createCapability(clause);
return ResourceUtils.toProvideCapability(cap);
}
static Capability createCapability(NativeCapability clause) throws Exception {
CapabilityBuilder c = new CapabilityBuilder("osgi.native");
c.addAttribute("osgi.native.osname", clause.osname);
c.addAttribute("osgi.native.osversion", clause.osversion);
c.addAttribute("osgi.native.processor", clause.processor);
c.addAttribute("osgi.native.language", clause.language);
Capability cap = c.synthetic();
return cap;
}
static void validateNativeCapability(NativeCapability clause) {
if (clause.osversion == null)
throw new IllegalArgumentException("osversion/osgi.native.osversion not set in ${native_capability}");
if (clause.osname.isEmpty())
throw new IllegalArgumentException("osname/osgi.native.osname not set in ${native_capability}");
if (clause.processor.isEmpty())
throw new IllegalArgumentException("processor/osgi.native.processor not set in ${native_capability}");
}
static void parseNativeCapabilityArgs(Processor p, String[] args, NativeCapability clause) throws Exception {
if (args.length == 1) {
OSInformation osi = new OSInformation();
clause.osname.addAll(Strings.split(osi.osnames));
clause.osversion = osi.osversion;
clause.processor.addAll(Arrays.asList(getProcessorAliases(System.getProperty("os.arch"))));
clause.language = Locale.getDefault().toString();
StringBuilder sb = new StringBuilder();
sb.append("osname=").append(System.getProperty("os.name"));
sb.append(";").append("osversion=").append(MavenVersion.cleanupVersion(System.getProperty("os.version")));
sb.append(";").append("processor=").append(System.getProperty("os.arch"));
sb.append(";").append("lang=").append(clause.language);
String advice = sb.toString();
} else {
String osname = null;
for (int i = 1; i < args.length; i++) {
String parts[] = args[i].split("\\s*=\\s*");
if (parts.length != 2)
throw new IllegalArgumentException(
"Illegal property syntax in \"" + args[i] + "\", use \"key=value\"");
String key = Strings.trim(parts[0]);
String value = Strings.trim(parts[1]);
boolean isList = value.indexOf(',') > 0;
switch (key) {
case "processor" :
case "osgi.native.processor" :
if (isList)
clause.processor.addAll(Strings.split(value));
else {
if ("arm".equals(value)) {
p.warning("The 'arm' processor is deprecated. Specify either 'arm_le' or 'arm_be'");
}
String[] processorAliases = getProcessorAliases(value);
if (processorAliases != null && processorAliases.length > 0) {
clause.processor.addAll(Arrays.asList(processorAliases));
} else {
clause.processor.add(value);
}
}
break;
case "osname" :
case "osgi.native.osname" :
if (isList)
clause.osname.addAll(Strings.split(value));
else {
if (osname == null) {
osname = value;
} else {
clause.osname.add(osname);
osname = value;
}
}
break;
case "osversion" :
case "osgi.native.osversion" :
if (clause.osversion == null) {
clause.osversion = Version.parseVersion(value);
} else
throw new IllegalArgumentException(
"osversion/osgi.native.osversion can only be set once in ${native_capability}");
break;
case "osgi.native.language" :
case "lang" :
if (clause.language != null)
throw new IllegalArgumentException(
"lang/osgi.native.lang can only be set once in ${native_capability}");
clause.language = value;
break;
}
}
if (osname != null) {
try {
OSInformation osi = new OSInformation(osname, clause.osversion.toString());
clause.osname.addAll(Strings.split(osi.osnames));
} catch (Exception e) {
clause.osname.add(osname);
}
}
}
}
public static class OSNameVersion {
public Version osversion;
public String osnames;
}
public static OSNameVersion getOperatingSystemAliases(String sysPropOsName, String sysPropOsVersion) {
OSNameVersion nc = new OSNameVersion();
if (sysPropOsName.startsWith("Windows")) {
if (sysPropOsVersion.startsWith("10.0")) {
nc.osversion = new Version(10, 0, 0);
nc.osnames = "Windows10,Windows 10,Win32";
} else if (sysPropOsVersion.startsWith("6.3")) {
nc.osversion = new Version(6, 3, 0);
nc.osnames = "Windows8.1,Windows 8.1,Win32";
} else if (sysPropOsVersion.startsWith("6.2")) {
nc.osversion = new Version(6, 2, 0);
nc.osnames = "Windows8,Windows 8,Win32";
} else if (sysPropOsVersion.startsWith("6.1")) {
nc.osversion = new Version(6, 1, 0);
nc.osnames = "Windows7,Windows 7,Win32";
} else if (sysPropOsVersion.startsWith("6.0")) {
nc.osversion = new Version(6, 0, 0);
nc.osnames = "WindowsVista,WinVista,Windows Vista,Win32";
} else if (sysPropOsVersion.startsWith("5.1")) {
nc.osversion = new Version(5, 1, 0);
nc.osnames = "WindowsXP,WinXP,Windows XP,Win32";
} else {
nc = null;
}
} else if (sysPropOsName.startsWith("Mac OS X")) {
nc.osversion = convertUnixKernelVersion(sysPropOsVersion);
nc.osnames = "MacOSX,Mac OS X";
return nc;
} else if (sysPropOsName.toLowerCase().startsWith("linux")) {
nc.osversion = convertUnixKernelVersion(sysPropOsVersion);
nc.osnames = "Linux";
} else if (sysPropOsName.startsWith("Solaris")) {
nc.osversion = convertUnixKernelVersion(sysPropOsVersion);
nc.osnames = "Solaris";
} else if (sysPropOsName.startsWith("AIX")) {
nc.osversion = convertUnixKernelVersion(sysPropOsVersion);
nc.osnames = "AIX";
} else if (sysPropOsName.startsWith("HP-UX")) {
nc.osversion = convertUnixKernelVersion(sysPropOsVersion);
nc.osnames = "HPUX,hp-ux";
}
return nc;
}
}