FELIX-4729 Added ability to convert Bundle-NativeCode to Require-Capability as defined in R6 spec.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1646550 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java b/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
index 9ce710b..151c8fb 100644
--- a/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
+++ b/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
@@ -35,8 +35,6 @@
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import java.util.NoSuchElementException;
import java.util.Set;
@@ -47,6 +45,7 @@
import org.apache.felix.framework.util.Util;
import org.apache.felix.framework.util.manifestparser.ManifestParser;
import org.apache.felix.framework.util.manifestparser.R4Library;
+import org.apache.felix.framework.util.manifestparser.R4LibraryClause;
import org.apache.felix.framework.wiring.BundleCapabilityImpl;
import org.apache.felix.framework.wiring.BundleWireImpl;
import org.osgi.framework.AdminPermission;
@@ -253,26 +252,24 @@
String osVersion = (String)m_configMap.get(FelixConstants.FRAMEWORK_OS_VERSION);
String userLang = (String)m_configMap.get(FelixConstants.FRAMEWORK_LANGUAGE);
Map<String, Object> attributes = new HashMap<String, Object>();
+
+ //Add all startup properties so we can match selection-filters
+ attributes.putAll(m_configMap);
if( osArchitecture != null )
{
- attributes.put(NativeNamespace.CAPABILITY_PROCESSOR_ATTRIBUTE, osArchitecture);
+ attributes.put(NativeNamespace.CAPABILITY_PROCESSOR_ATTRIBUTE, R4LibraryClause.getProcessorWithAliases(osArchitecture));
}
if( osName != null)
{
- attributes.put(NativeNamespace.CAPABILITY_OSNAME_ATTRIBUTE, osName);
+ attributes.put(NativeNamespace.CAPABILITY_OSNAME_ATTRIBUTE, R4LibraryClause.getOsNameWithAliases(osName));
}
if( osVersion != null)
{
- Pattern versionPattern = Pattern.compile("\\d+\\.?\\d*\\.?\\d*");
- Matcher matcher = versionPattern.matcher(osVersion);
- if(matcher.find())
- {
- osVersion = matcher.group();
- }
- attributes.put(NativeNamespace.CAPABILITY_OSVERSION_ATTRIBUTE, new Version(osVersion));
+ osVersion = R4LibraryClause.formatOSVersion(osVersion);
+ attributes.put(NativeNamespace.CAPABILITY_OSVERSION_ATTRIBUTE, Version.parseVersion(osVersion));
}
if( userLang != null)
diff --git a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
index 672fd2f..1cf00b2 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
@@ -19,6 +19,7 @@
package org.apache.felix.framework.util.manifestparser;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -41,6 +42,7 @@
import org.osgi.framework.namespace.BundleNamespace;
import org.osgi.framework.namespace.ExecutionEnvironmentNamespace;
import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.framework.namespace.NativeNamespace;
import org.osgi.framework.wiring.BundleCapability;
import org.osgi.framework.wiring.BundleRequirement;
import org.osgi.framework.wiring.BundleRevision;
@@ -243,24 +245,6 @@
exportCaps = calculateImplicitUses(exportCaps, allImportClauses);
}
- // Combine all capabilities.
- m_capabilities = new ArrayList(
- capList.size() + exportCaps.size() + provideCaps.size());
- m_capabilities.addAll(capList);
- m_capabilities.addAll(exportCaps);
- m_capabilities.addAll(provideCaps);
-
- // Combine all requirements.
- m_requirements = new ArrayList(
- hostReqs.size() + importReqs.size() + rbReqs.size()
- + requireReqs.size() + dynamicReqs.size() + breeReqs.size());
- m_requirements.addAll(hostReqs);
- m_requirements.addAll(importReqs);
- m_requirements.addAll(rbReqs);
- m_requirements.addAll(requireReqs);
- m_requirements.addAll(dynamicReqs);
- m_requirements.addAll(breeReqs);
-
//
// Parse Bundle-NativeCode.
//
@@ -279,6 +263,27 @@
m_libraryHeadersOptional = true;
m_libraryClauses.remove(m_libraryClauses.size() - 1);
}
+
+ List<BundleRequirement> nativeCodeReqs = convertNativeCode(owner, m_libraryClauses, m_libraryHeadersOptional);
+
+ // Combine all requirements.
+ m_requirements = new ArrayList(
+ hostReqs.size() + importReqs.size() + rbReqs.size()
+ + requireReqs.size() + dynamicReqs.size() + breeReqs.size());
+ m_requirements.addAll(hostReqs);
+ m_requirements.addAll(importReqs);
+ m_requirements.addAll(rbReqs);
+ m_requirements.addAll(requireReqs);
+ m_requirements.addAll(dynamicReqs);
+ m_requirements.addAll(breeReqs);
+ m_requirements.addAll(nativeCodeReqs);
+
+ // Combine all capabilities.
+ m_capabilities = new ArrayList(
+ capList.size() + exportCaps.size() + provideCaps.size());
+ m_capabilities.addAll(capList);
+ m_capabilities.addAll(exportCaps);
+ m_capabilities.addAll(provideCaps);
//
// Parse activation policy.
@@ -601,6 +606,123 @@
return reqList;
}
+
+ static List<BundleRequirement> convertNativeCode(BundleRevision owner, List<R4LibraryClause> nativeLibraryClauses, boolean hasOptionalLibraryDirective)
+ {
+ List<BundleRequirement> result = new ArrayList<BundleRequirement>();
+
+ List<SimpleFilter> nativeFilterClauseList = new ArrayList<SimpleFilter>();
+
+ if(nativeLibraryClauses != null)
+ {
+ for(R4LibraryClause clause: nativeLibraryClauses)
+ {
+ String[] osNameArray = clause.getOSNames();
+ String[] osVersionArray = clause.getOSVersions();
+ String[] processorArray = clause.getProcessors();
+ String[] languageArray = clause.getLanguages();
+
+ String currentSelectionFilter = clause.getSelectionFilter();
+
+ List<SimpleFilter> nativeFilterList = new ArrayList<SimpleFilter>();
+ if(osNameArray != null && osNameArray.length > 0)
+ {
+ nativeFilterList.add(buildFilterFromArray(NativeNamespace.CAPABILITY_OSNAME_ATTRIBUTE, osNameArray, SimpleFilter.APPROX));
+ }
+
+ if(osVersionArray != null && osVersionArray.length > 0)
+ {
+ nativeFilterList.add(buildFilterFromArray(NativeNamespace.CAPABILITY_OSVERSION_ATTRIBUTE, osVersionArray, SimpleFilter.EQ));
+ }
+
+ if(processorArray != null && processorArray.length > 0)
+ {
+ nativeFilterList.add(buildFilterFromArray(NativeNamespace.CAPABILITY_PROCESSOR_ATTRIBUTE, processorArray, SimpleFilter.APPROX));
+ }
+
+ if(languageArray != null && languageArray.length > 0)
+ {
+ nativeFilterList.add(buildFilterFromArray(NativeNamespace.CAPABILITY_LANGUAGE_ATTRIBUTE, languageArray, SimpleFilter.APPROX));
+ }
+
+ if(currentSelectionFilter != null)
+ {
+ nativeFilterList.add(SimpleFilter.parse(currentSelectionFilter));
+ }
+
+ if(!nativeFilterList.isEmpty())
+ {
+ SimpleFilter nativeClauseFilter = new SimpleFilter(null, nativeFilterList, SimpleFilter.AND);
+ nativeFilterClauseList.add(nativeClauseFilter);
+ }
+ }
+
+ Map<String, String> requirementDirectives = new HashMap<String, String>();
+
+ SimpleFilter consolidatedNativeFilter = null;
+
+ if(hasOptionalLibraryDirective)
+ {
+ requirementDirectives.put(NativeNamespace.REQUIREMENT_RESOLUTION_DIRECTIVE, NativeNamespace.RESOLUTION_OPTIONAL);
+ }
+
+ if(nativeFilterClauseList.size() > 1)
+ {
+ consolidatedNativeFilter = new SimpleFilter(null, nativeFilterClauseList, SimpleFilter.OR);
+
+ requirementDirectives.put(NativeNamespace.REQUIREMENT_FILTER_DIRECTIVE, consolidatedNativeFilter.toString());
+ }
+ else if(nativeFilterClauseList.size() == 1)
+ {
+ consolidatedNativeFilter = nativeFilterClauseList.get(0);
+
+ requirementDirectives.put(NativeNamespace.REQUIREMENT_FILTER_DIRECTIVE, consolidatedNativeFilter.toString());
+ }
+
+ if(requirementDirectives.size() > 0)
+ {
+ result.add(new BundleRequirementImpl(owner, NativeNamespace.NATIVE_NAMESPACE, requirementDirectives,
+ Collections.<String, Object>emptyMap(),
+ consolidatedNativeFilter));
+ }
+
+ }
+
+ return result;
+ }
+
+ private static SimpleFilter buildFilterFromArray(String attributeName, String[] stringArray, int operation)
+ {
+ SimpleFilter result = null;
+ List<SimpleFilter> filterSet = new ArrayList<SimpleFilter>();
+
+ if(stringArray != null)
+ {
+ for(String currentValue : stringArray)
+ {
+ filterSet.add(new SimpleFilter(attributeName, currentValue.toLowerCase(), operation));
+ }
+
+ if(filterSet.size() == 1)
+ {
+ result = filterSet.get(0);
+ }
+ else
+ {
+ result = new SimpleFilter(null, filterSet, SimpleFilter.OR);
+ }
+ }
+
+ return result;
+ }
+
+ private static void addStringArrayToSet(String[] array, Set<String> set)
+ {
+ if(array != null)
+ {
+ set.addAll(Arrays.asList(array));
+ }
+ }
private static List<ParsedHeaderClause> normalizeProvideCapabilityClauses(
Logger logger, List<ParsedHeaderClause> clauses, String mv)
@@ -722,6 +844,14 @@
+ path
+ "' namespace.");
}
+
+ if(path.startsWith(NativeNamespace.NATIVE_NAMESPACE) && (owner == null ||
+ !FelixConstants.SYSTEM_BUNDLE_SYMBOLICNAME.equals(owner.getSymbolicName())))
+ {
+ throw new BundleException("Only System Bundle can use Provide-Capability for '"
+ + path
+ + "' namespace.", BundleException.MANIFEST_ERROR);
+ }
// Create package capability and add to capability list.
capList.add(
diff --git a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/R4LibraryClause.java b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/R4LibraryClause.java
index 769c214..b59d18b 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/R4LibraryClause.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/R4LibraryClause.java
@@ -19,14 +19,19 @@
package org.apache.felix.framework.util.manifestparser;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Dictionary;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.apache.felix.framework.Logger;
import org.apache.felix.framework.util.FelixConstants;
@@ -41,10 +46,12 @@
{
private static final String OS_AIX = "aix";
private static final String OS_DIGITALUNIX = "digitalunix";
+ private static final String OS_EPOC = "epoc32";
private static final String OS_HPUX = "hpux";
private static final String OS_IRIX = "irix";
private static final String OS_LINUX = "linux";
private static final String OS_MACOS = "macos";
+ private static final String OS_MACOSX = "macosx";
private static final String OS_NETBSD = "netbsd";
private static final String OS_NETWARE = "netware";
private static final String OS_OPENBSD = "openbsd";
@@ -67,6 +74,19 @@
private static final String OS_WINDOWS_VISTA = "windowsvista";
private static final String OS_WINDOWS_XP = "windowsxp";
private static final String OS_WIN_32 = "win32";
+
+ private static final String PROC_X86_64 = "x86-64";
+ private static final String PROC_X86 = "x86";
+ private static final String PROC_68K = "68k";
+ private static final String PROC_ARM_LE = "arm_le";
+ private static final String PROC_ARM_BE = "arm_be";
+ private static final String PROC_ARM = "arm";
+ private static final String PROC_ALPHA = "alpha";
+ private static final String PROC_IGNITE = "ignite";
+ private static final String PROC_MIPS = "mips";
+ private static final String PROC_PARISC = "parisc";
+ private static final String PROC_POWER_PC = "powerpc";
+ private static final String PROC_SPARC = "sparc";
/* Storing the OS names in a map as this is quicker to look up than a list.
*/
@@ -127,12 +147,9 @@
public R4LibraryClause(R4LibraryClause library)
{
- m_libraryEntries = library.m_libraryEntries;
- m_osnames = library.m_osnames;
- m_osversions = library.m_osversions;
- m_processors = library.m_processors;
- m_languages = library.m_languages;
- m_selectionFilter = library.m_selectionFilter;
+ this(library.m_libraryEntries, library.m_osnames, library.m_osversions,
+ library.m_processors, library.m_languages,
+ library.m_selectionFilter);
}
public String[] getLibraryEntries()
@@ -167,19 +184,19 @@
public boolean match(Map configMap) throws BundleException
{
- String normal_osname = normalizeOSName((String) configMap.get(Constants.FRAMEWORK_OS_NAME));
- String normal_processor = normalizeProcessor((String) configMap.get(Constants.FRAMEWORK_PROCESSOR));
- String normal_osversion = normalizeOSVersion((String) configMap.get(Constants.FRAMEWORK_OS_VERSION));
- String normal_language = (String) configMap.get(Constants.FRAMEWORK_LANGUAGE);
+ String osName = (String) configMap.get(FelixConstants.FRAMEWORK_OS_NAME);
+ String processorName = (String) configMap.get(FelixConstants.FRAMEWORK_PROCESSOR);
+ String osVersion = (String) configMap.get(FelixConstants.FRAMEWORK_OS_VERSION);
+ String language = (String) configMap.get(FelixConstants.FRAMEWORK_LANGUAGE);
// Check library's osname.
- if (!checkOSNames(normal_osname, getOSNames()))
+ if (!checkOSNames(osName, getOSNames()))
{
return false;
}
// Check library's processor.
- if (!checkProcessors(normal_processor, getProcessors()))
+ if (!checkProcessors(processorName, getProcessors()))
{
return false;
}
@@ -187,7 +204,7 @@
// Check library's osversion if specified.
if ((getOSVersions() != null) &&
(getOSVersions().length > 0) &&
- !checkOSVersions(normal_osversion, getOSVersions()))
+ !checkOSVersions(osVersion, getOSVersions()))
{
return false;
}
@@ -195,7 +212,7 @@
// Check library's language if specified.
if ((getLanguages() != null) &&
(getLanguages().length > 0) &&
- !checkLanguages(normal_language, getLanguages()))
+ !checkLanguages(language, getLanguages()))
{
return false;
}
@@ -211,42 +228,49 @@
return true;
}
- private boolean checkOSNames(String currentOSName, String[] osnames)
+ private boolean checkOSNames(String osName, String[] osnames)
{
- boolean win32 = currentOSName.startsWith("win") && !currentOSName.equals(OS_WINDOWS_CE);
-
- for (int i = 0; (osnames != null) && (i < osnames.length); i++)
+ List<String> capabilityOsNames = getOsNameWithAliases(osName);
+ if (capabilityOsNames != null && osnames != null)
{
- if (osnames[i].equals(currentOSName) ||
- (OS_WIN_32.equals(osnames[i]) && win32))
+ for (String curOsName : osnames)
{
- return true;
+ if (capabilityOsNames.contains(curOsName))
+ {
+ return true;
+ }
+
}
}
return false;
}
- private boolean checkProcessors(String currentProcessor, String[] processors)
+ private boolean checkProcessors(String processorName, String[] processors)
{
- for (int i = 0; (processors != null) && (i < processors.length); i++)
+ List<String> capabilitiesProcessors = getProcessorWithAliases(processorName);
+ if (capabilitiesProcessors != null && processors != null)
{
- if (processors[i].equals(currentProcessor))
+ for (String currentProcessor : processors)
{
- return true;
+ if (capabilitiesProcessors.contains(currentProcessor))
+ {
+ return true;
+ }
}
}
return false;
}
- private boolean checkOSVersions(String currentOSVersion, String[] osversions)
+ private boolean checkOSVersions(String osVersion, String[] osversions)
throws BundleException
{
+ Version currentOSVersion = Version.parseVersion(formatOSVersion(osVersion));
for (int i = 0; (osversions != null) && (i < osversions.length); i++)
{
try
{
VersionRange range = VersionRange.parse(osversions[i]);
- if (range.isInRange(new Version(currentOSVersion)))
+ if (range.isInRange(currentOSVersion))
{
return true;
}
@@ -304,6 +328,7 @@
return null;
}
+ s = s.trim();
if (s.equals(FelixConstants.BUNDLE_NATIVECODE_OPTIONAL))
{
return new R4LibraryClause(null, null, null, null, null, null);
@@ -368,10 +393,16 @@
value = value.substring(1);
}
}
+
+ if (value != null)
+ {
+ value = value.toLowerCase();
+ }
+
// Add the value to its corresponding property list.
if (property.equals(Constants.BUNDLE_NATIVECODE_OSNAME))
{
- osNameList.add(normalizeOSName(value));
+ osNameList.add(value);
}
else if (property.equals(Constants.BUNDLE_NATIVECODE_OSVERSION))
{
@@ -379,7 +410,7 @@
}
else if (property.equals(Constants.BUNDLE_NATIVECODE_PROCESSOR))
{
- processorList.add(normalizeProcessor(value));
+ processorList.add(value);
}
else if (property.equals(Constants.BUNDLE_NATIVECODE_LANGUAGE))
{
@@ -387,7 +418,7 @@
}
else if (property.equals(Constants.SELECTION_FILTER_ATTRIBUTE))
{
-// TODO: NATIVE - I believe we can have multiple selection filters too.
+ // TODO: NATIVE - I believe we can have multiple selection filters too.
selectionFilter = value;
}
}
@@ -417,6 +448,250 @@
}
}
+ public static String formatOSVersion(String value)
+ {
+ // Header: 'Bundle-NativeCode', Parameter: 'osversion'
+ // Standardized 'osversion': major.minor.micro, only digits
+ try
+ {
+ Pattern versionPattern = Pattern.compile("\\d+\\.?\\d*\\.?\\d*");
+ Matcher matcher = versionPattern.matcher(value);
+ if (matcher.find())
+ {
+ value = matcher.group();
+ }
+ return Version.parseVersion(value).toString();
+ }
+ catch (Exception ex)
+ {
+ return Version.emptyVersion.toString();
+ }
+ }
+
+ public static List<String> getOsNameWithAliases(String osName)
+ {
+ //Can't assume this has been normalized
+ osName = normalizeOSName(osName);
+
+ List<String> result = null;
+ //
+ if (osName.startsWith("win"))
+ {
+ // Per spec windows ce does not include win32 alias
+ if (osName.equals(OS_WINDOWS_CE))
+ {
+ result = Arrays.asList("windowsce", "wince", "windows ce");
+ }
+ else
+ {
+ //Accumulate windows aliases. win32 may match many versions of windows.
+ Set<String> windowsOsList = new HashSet<String>();
+
+ if (osName.equals(OS_WINDOWS_95)|| osName.equals(OS_WIN_32))
+ {
+ windowsOsList.addAll(Arrays.asList("windows95", "win95",
+ "windows 95", OS_WIN_32));
+ }
+
+ if (osName.equals(OS_WINDOWS_98) || osName.equals(OS_WIN_32))
+ {
+ windowsOsList.addAll(Arrays.asList("windows98",
+ "windows 98", OS_WIN_32));
+ }
+
+ if (osName.equals(OS_WINDOWS_NT) || osName.equals(OS_WIN_32))
+ {
+ windowsOsList.addAll(Arrays.asList("windowsnt", "winnt",
+ "windows nt", OS_WIN_32));
+ }
+
+ if (osName.equals(OS_WINDOWS_2000) || osName.equals(OS_WIN_32))
+ {
+ windowsOsList.addAll(Arrays.asList("windows2000",
+ "win2000", "windows 2000", OS_WIN_32));
+ }
+
+ if (osName.equals(OS_WINDOWS_2003) || osName.equals(OS_WIN_32))
+ {
+ windowsOsList.addAll(Arrays.asList("windows2003",
+ "win2003", "windows 2003", OS_WIN_32,
+ "windows server 2003", "windowsserver2003"));
+ }
+
+ if (osName.equals(OS_WINDOWS_SERVER_2008) || osName.equals(OS_WIN_32))
+ {
+ windowsOsList.addAll(Arrays.asList("windows2008",
+ "win2008", "windows 2008", OS_WIN_32,
+ "windows server 2008", "windowsserver2008"));
+ }
+
+ if (osName.equals(OS_WINDOWS_SERVER_2012) || osName.equals(OS_WIN_32))
+ {
+ windowsOsList.addAll(Arrays.asList("windows2012",
+ "win2012", "windows 2012", OS_WIN_32,
+ "windows server 2012", "windowsserver2012"));
+ }
+
+ if (osName.equals(OS_WINDOWS_XP) || osName.equals(OS_WIN_32))
+ {
+ windowsOsList.addAll(Arrays.asList("windowsxp", "winxp",
+ "windows xp", OS_WIN_32));
+ }
+
+ if (osName.equals(OS_WINDOWS_VISTA) || osName.equals(OS_WIN_32))
+ {
+ windowsOsList.addAll(Arrays.asList("windowsvista",
+ "windows vista", OS_WIN_32));
+ }
+
+ if (osName.equals(OS_WINDOWS_7) || osName.equals(OS_WIN_32))
+ {
+ windowsOsList.addAll(Arrays.asList("windows7", "windows 7",
+ OS_WIN_32));
+ }
+
+ if (osName.equals(OS_WINDOWS_8) || osName.equals(OS_WIN_32))
+ {
+ windowsOsList.addAll(Arrays.asList("windows8", "windows 8",
+ OS_WIN_32));
+ }
+
+ if (osName.equals(OS_WINDOWS_9) || osName.equals(OS_WIN_32))
+ {
+ windowsOsList.addAll(Arrays.asList("windows9", "windows 9",
+ OS_WIN_32));
+ }
+
+ if (windowsOsList.isEmpty())
+ {
+ windowsOsList.add(osName);
+ }
+ result = new ArrayList<String>(windowsOsList);
+ }
+
+ }
+ else if (osName.equals(OS_LINUX))
+ {
+ result = Collections.singletonList(OS_LINUX);
+ }
+ else if (osName.equals(OS_AIX))
+ {
+ result = Collections.singletonList(OS_AIX);
+ }
+ else if (osName.equals(OS_DIGITALUNIX))
+ {
+ result = Collections.singletonList(OS_DIGITALUNIX);
+ }
+ else if (osName.equals(OS_EPOC))
+ {
+ result = Arrays.asList(OS_EPOC, "symbianos");
+ }
+ else if (osName.equals(OS_HPUX))
+ {
+ result = Arrays.asList(OS_HPUX, "hp-ux");
+ }
+ else if (osName.equals(OS_IRIX))
+ {
+ result = Collections.singletonList(OS_IRIX);
+ }
+ else if (osName.equals(OS_MACOSX))
+ {
+ result = Arrays.asList(OS_MACOSX, "mac os x");
+ }
+ else if (osName.equals(OS_MACOS))
+ {
+ result = Arrays.asList(OS_MACOS, "mac os");
+ }
+ else if (osName.equals(OS_NETWARE))
+ {
+ result = Collections.singletonList(OS_NETWARE);
+ }
+ else if (osName.equals(OS_OPENBSD))
+ {
+ result = Collections.singletonList(OS_OPENBSD);
+ }
+ else if (osName.equals(OS_NETBSD))
+ {
+ result = Collections.singletonList(OS_NETBSD);
+ }
+ else if (osName.equals(OS_OS2))
+ {
+ result = Arrays.asList(OS_OS2, "os/2");
+ }
+ else if (osName.equals(OS_QNX))
+ {
+ result = Arrays.asList(OS_QNX, "procnto");
+ }
+ else if (osName.equals(OS_SOLARIS))
+ {
+ result = Collections.singletonList(OS_SOLARIS);
+ }
+ else if (osName.equals(OS_SUNOS))
+ {
+ result = Collections.singletonList(OS_SUNOS);
+ }
+ else if (osName.equals(OS_VXWORKS))
+ {
+ result = Collections.singletonList(OS_VXWORKS);
+ }
+ else
+ {
+ result = Collections.singletonList(osName);
+ }
+
+ return Collections.unmodifiableList(result);
+ }
+
+ public static List<String> getProcessorWithAliases(String processor)
+ {
+ //Can't assume this has been normalized
+ processor = normalizeProcessor(processor);
+
+ List<String> result = null;
+ if (processor.equals(PROC_X86_64))
+ {
+ result = Arrays.asList(PROC_X86_64, "amd64", "em64t", "x86_64");
+ }
+ else if (processor.equals(PROC_X86))
+ {
+ result = Arrays.asList(PROC_X86, "pentium", "i386", "i486", "i586",
+ "i686");
+ }
+ else if (processor.equals(PROC_68K))
+ {
+ result = Arrays.asList(PROC_68K);
+ }
+ else if (processor.equals(PROC_ALPHA))
+ {
+ result = Arrays.asList(PROC_ALPHA);
+ }
+ else if (processor.equals(PROC_IGNITE))
+ {
+ result = Arrays.asList(PROC_IGNITE, "psc1k");
+ }
+ else if (processor.equals(PROC_MIPS))
+ {
+ result = Arrays.asList(PROC_MIPS);
+ }
+ else if (processor.equals(PROC_PARISC))
+ {
+ result = Arrays.asList(PROC_PARISC);
+ }
+ else if (processor.equals(PROC_POWER_PC))
+ {
+ result = Arrays.asList(PROC_POWER_PC, "power", "ppc");
+ }
+ else if (processor.equals(PROC_SPARC))
+ {
+ result = Arrays.asList(PROC_SPARC);
+ }
+ else
+ {
+ result = Collections.singletonList(processor);
+ }
+ return Collections.unmodifiableList(result);
+ }
+
public static String normalizeOSName(String value)
{
if (NORMALIZED_OS_NAMES.containsKey(value))
@@ -508,6 +783,10 @@
{
return OS_IRIX;
}
+ else if (value.startsWith(OS_MACOSX) || value.startsWith("mac os x"))
+ {
+ return OS_MACOSX;
+ }
else if (value.startsWith(OS_MACOS) || value.startsWith("mac os"))
{
return OS_MACOS;
@@ -551,49 +830,57 @@
{
value = value.toLowerCase();
- if (value.startsWith("x86-64") || value.startsWith("amd64") ||
+ if (value.startsWith(PROC_X86_64) || value.startsWith("amd64") ||
value.startsWith("em64") || value.startsWith("x86_64"))
{
- return "x86-64";
+ return PROC_X86_64;
}
- else if (value.startsWith("x86") || value.startsWith("pentium")
+ else if (value.startsWith(PROC_X86) || value.startsWith("pentium")
|| value.startsWith("i386") || value.startsWith("i486")
|| value.startsWith("i586") || value.startsWith("i686"))
{
- return "x86";
+ return PROC_X86;
}
- else if (value.startsWith("68k"))
+ else if (value.startsWith(PROC_68K))
{
- return "68k";
+ return PROC_68K;
}
- else if (value.startsWith("arm"))
+ else if (value.startsWith(PROC_ARM_LE))
{
- return "arm";
+ return PROC_ARM_LE;
}
- else if (value.startsWith("alpha"))
+ else if (value.startsWith(PROC_ARM_BE))
{
- return "alpha";
+ return PROC_ARM_BE;
}
- else if (value.startsWith("ignite") || value.startsWith("psc1k"))
+ else if (value.startsWith(PROC_ARM))
{
- return "ignite";
+ return PROC_ARM;
}
- else if (value.startsWith("mips"))
+ else if (value.startsWith(PROC_ALPHA))
{
- return "mips";
+ return PROC_ALPHA;
}
- else if (value.startsWith("parisc"))
+ else if (value.startsWith(PROC_IGNITE) || value.startsWith("psc1k"))
{
- return "parisc";
+ return PROC_IGNITE;
}
- else if (value.startsWith("powerpc") || value.startsWith("power")
+ else if (value.startsWith(PROC_MIPS))
+ {
+ return PROC_MIPS;
+ }
+ else if (value.startsWith(PROC_PARISC))
+ {
+ return PROC_PARISC;
+ }
+ else if (value.startsWith(PROC_POWER_PC) || value.startsWith("power")
|| value.startsWith("ppc"))
{
- return "powerpc";
+ return PROC_POWER_PC;
}
- else if (value.startsWith("sparc"))
+ else if (value.startsWith(PROC_SPARC))
{
- return "sparc";
+ return PROC_SPARC;
}
return value;
}
diff --git a/framework/src/test/java/org/apache/felix/framework/ExtensionManagerTest.java b/framework/src/test/java/org/apache/felix/framework/ExtensionManagerTest.java
index 63e4a79..a281562 100644
--- a/framework/src/test/java/org/apache/felix/framework/ExtensionManagerTest.java
+++ b/framework/src/test/java/org/apache/felix/framework/ExtensionManagerTest.java
@@ -25,6 +25,8 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.jar.JarOutputStream;
@@ -88,12 +90,12 @@
NativeNamespace.CAPABILITY_LANGUAGE_ATTRIBUTE));
assertEquals(
"Native Processor should be same as framework Processor",
- "x86_64",
+ Arrays.asList("x86-64", "amd64", "em64t", "x86_64"),
nativeBundleCapability.getAttributes().get(
NativeNamespace.CAPABILITY_PROCESSOR_ATTRIBUTE));
assertEquals(
"Native OS Name should be the same as the framework os name",
- "windows8",
+ Arrays.asList("windows8", "windows 8", "win32"),
nativeBundleCapability.getAttributes().get(
NativeNamespace.CAPABILITY_OSNAME_ATTRIBUTE));
assertEquals(
diff --git a/framework/src/test/java/org/apache/felix/framework/util/manifestparser/ManifestParserTest.java b/framework/src/test/java/org/apache/felix/framework/util/manifestparser/ManifestParserTest.java
index 194458d..3d826f4 100644
--- a/framework/src/test/java/org/apache/felix/framework/util/manifestparser/ManifestParserTest.java
+++ b/framework/src/test/java/org/apache/felix/framework/util/manifestparser/ManifestParserTest.java
@@ -18,19 +18,27 @@
*/
package org.apache.felix.framework.util.manifestparser;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import static org.mockito.Mockito.*;
import junit.framework.TestCase;
+import org.apache.felix.framework.util.FelixConstants;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.Version;
import org.osgi.framework.namespace.IdentityNamespace;
import org.osgi.framework.namespace.NativeNamespace;
import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
public class ManifestParserTest extends TestCase
{
@@ -80,14 +88,16 @@
public void testNativeCapability() throws BundleException {
Map<String, String> headers = new HashMap<String, String>();
headers.put(Constants.BUNDLE_MANIFESTVERSION, "2");
- headers.put(Constants.BUNDLE_SYMBOLICNAME, "foo.bar");
+ headers.put(Constants.BUNDLE_SYMBOLICNAME, FelixConstants.SYSTEM_BUNDLE_SYMBOLICNAME);
headers.put(Constants.PROVIDE_CAPABILITY, " osgi.native;" +
"osgi.native.osname:List<String>=\"Windows7,Windows 7,Win7,Win32\";"+
"osgi.native.osversion:Version=\"7.0\";"+
"osgi.native.processor:List<String>=\"x86-64,amd64,em64t,x86_64\";"+
"osgi.native.language=\"en\"");
+ BundleRevision mockBundleRevision = mock(BundleRevision.class);
+ when(mockBundleRevision.getSymbolicName()).thenReturn(FelixConstants.SYSTEM_BUNDLE_SYMBOLICNAME);
- ManifestParser mp = new ManifestParser(null, null, null, headers);
+ ManifestParser mp = new ManifestParser(null, null, mockBundleRevision, headers);
BundleCapability ic = findCapability(mp.getCapabilities(), NativeNamespace.NATIVE_NAMESPACE);
@@ -99,6 +109,39 @@
assertEquals(4, nativeProcesserList.size());
}
+
+ public void testConvertNativeCode() throws InvalidSyntaxException
+ {
+ List<R4LibraryClause> nativeLibraryClauses = new ArrayList<R4LibraryClause>();
+ String[] libraryFiles = {"lib/http.dll", "lib/zlib.dll"};
+ String[] osNames = {"Windows95", "Windows98", "WindowsNT"};
+ String[] processors = {"x86"};
+ String[] osVersions = null;
+ String[] languages = {"en", "se"};
+ String selectionFilter = "(com.acme.windowing=win32)";
+ R4LibraryClause clause = new R4LibraryClause(libraryFiles, osNames, processors, osVersions, languages, selectionFilter);
+ BundleRevision owner = mock(BundleRevision.class);
+ nativeLibraryClauses.add(clause);
+
+ List<BundleRequirement> nativeBundleReq = ManifestParser.convertNativeCode(owner, nativeLibraryClauses, false);
+
+ BundleRequirement ir = findRequirement(nativeBundleReq, NativeNamespace.NATIVE_NAMESPACE);
+
+ String filterStr = (String)ir.getDirectives().get(NativeNamespace.REQUIREMENT_FILTER_DIRECTIVE);
+
+ Filter actualFilter = FrameworkUtil.createFilter(filterStr);
+
+ Filter expectedFilter = FrameworkUtil.createFilter("(&(|" +
+ "(osgi.native.osname~=windows95)(osgi.native.osname~=windows98)(osgi.native.osname~=windowsnt)" +
+ ")" +
+ "(osgi.native.processor~=x86)" +
+ "(|(osgi.native.language~=en)" +
+ "(osgi.native.language~=se)" +
+ ")"+
+ "(com.acme.windowing=win32))");
+ assertEquals("Filter Should contain native requirements", expectedFilter, actualFilter);
+
+ }
private BundleCapability findCapability(Collection<BundleCapability> capabilities, String namespace)
{
@@ -111,4 +154,16 @@
}
return null;
}
+
+ private BundleRequirement findRequirement(Collection<BundleRequirement> requirements, String namespace)
+ {
+ for(BundleRequirement requirement: requirements)
+ {
+ if(namespace.equals(requirement.getNamespace()))
+ {
+ return requirement;
+ }
+ }
+ return null;
+ }
}
diff --git a/framework/src/test/java/org/apache/felix/framework/util/manifestparser/R4LibraryClauseTest.java b/framework/src/test/java/org/apache/felix/framework/util/manifestparser/R4LibraryClauseTest.java
index b5effd2..70ee7e8 100644
--- a/framework/src/test/java/org/apache/felix/framework/util/manifestparser/R4LibraryClauseTest.java
+++ b/framework/src/test/java/org/apache/felix/framework/util/manifestparser/R4LibraryClauseTest.java
@@ -41,7 +41,7 @@
assertEquals("digitalunix", R4LibraryClause.normalizeOSName("digitalunix_blah"));
assertEquals("hpux", R4LibraryClause.normalizeOSName("HPUX-999"));
assertEquals("irix", R4LibraryClause.normalizeOSName("Irixxxx"));
- assertEquals("macos", R4LibraryClause.normalizeOSName("mac OS X"));
+ assertEquals("macosx", R4LibraryClause.normalizeOSName("mac OS X"));
assertEquals("netware", R4LibraryClause.normalizeOSName("Netware"));
assertEquals("openbsd", R4LibraryClause.normalizeOSName("OpenBSD-0000"));
assertEquals("netbsd", R4LibraryClause.normalizeOSName("netbsd "));
@@ -81,4 +81,65 @@
assertEquals("windowsxp", R4LibraryClause.normalizeOSName("windowsxp"));
assertEquals("win32", R4LibraryClause.normalizeOSName("win32"));
}
+
+ public void testgetOsNameWithAliases() {
+ assertTrue(R4LibraryClause.getOsNameWithAliases("win 32").contains("win32"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("Win*").contains("win32"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("Windows 95").contains("windows95"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("Windows 98").contains("windows98"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("WinNT").contains("windowsnt"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("Win2000").contains("windows2000"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("Win2003").contains("windows2003"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("Windows Server 2008").contains("windowsserver2008"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("Windows Server 2012").contains("windowsserver2012"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("WinXP").contains("windowsxp"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("WinCE").contains("windowsce"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("WinVista").contains("windowsvista"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("Windows 7").contains("windows7"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("Win8").contains("windows8"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("Linux1.2.3").contains("linux"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("AIX-4.5.6").contains("aix"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("digitalunix_blah").contains("digitalunix"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("HPUX-999").contains("hpux"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("Irixxxx").contains("irix"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("mac OS X").contains("mac os x"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("Netware").contains("netware"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("OpenBSD-0000").contains("openbsd"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("netbsd ").contains("netbsd"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("os/2").contains("os2"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("procnto").contains("qnx"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("Solaris 9").contains("solaris"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("SunOS8").contains("sunos"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("VxWorks").contains("vxworks"));
+
+ // Try all the already normalized names
+ assertTrue(R4LibraryClause.getOsNameWithAliases("aix").contains("aix"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("digitalunix").contains("digitalunix"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("hpux").contains("hpux"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("irix").contains("irix"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("linux").contains("linux"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("mac os").contains("mac os"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("netbsd").contains("netbsd"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("netware").contains("netware"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("openbsd").contains("openbsd"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("os2").contains("os2"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("qnx").contains("qnx"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("solaris").contains("solaris"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("sunos").contains("sunos"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("vxworks").contains("vxworks"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("windows2000").contains("windows2000"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("windows2003").contains("windows2003"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("windows7").contains("windows7"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("windows8").contains("windows8"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("windows9").contains("windows9"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("windows95").contains("windows95"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("windows98").contains("windows98"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("windowsce").contains("windowsce"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("windowsnt").contains("windowsnt"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("windowsserver2008").contains("windowsserver2008"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("windowsserver2012").contains("windowsserver2012"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("windowsvista").contains("windowsvista"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("windowsxp").contains("windowsxp"));
+ assertTrue(R4LibraryClause.getOsNameWithAliases("win32").contains("win32"));
+ }
}