FELIX-3883 Brokeup the os and processor configs into separate property keys. 

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1650432 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/Felix.java b/framework/src/main/java/org/apache/felix/framework/Felix.java
index 2a409f5..2b418f3 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -4587,17 +4587,18 @@
         m_configMutableMap.put(
             FelixConstants.FELIX_VERSION_PROPERTY, getFrameworkVersion());
 
+        Properties defaultProperties = Util.loadDefaultProperties(m_logger);
         // Set supported execution environments to default value,
         // if not explicitly configured.
-        loadFromDefaultIfNotDefined(Constants.FRAMEWORK_EXECUTIONENVIRONMENT);
+        loadFromDefaultIfNotDefined(defaultProperties, Constants.FRAMEWORK_EXECUTIONENVIRONMENT);
 
         // Set supported native capabilities to default value,
         // if not explicitly configured.
-        loadFromDefaultIfNotDefined(FelixConstants.NATIVE_OS_NAME_ALIASES);
-        loadFromDefaultIfNotDefined(FelixConstants.NATIVE_PROC_NAME_ALIASES);
+        loadPrefixFromDefaultIfNotDefined(m_configMutableMap, defaultProperties, FelixConstants.NATIVE_OS_NAME_ALIAS_PREFIX);
+        loadPrefixFromDefaultIfNotDefined(m_configMutableMap, defaultProperties, FelixConstants.NATIVE_PROC_NAME_ALIAS_PREFIX);
     }
 
-    private void loadFromDefaultIfNotDefined(String propertyName)
+    private void loadFromDefaultIfNotDefined(Properties defaultProperties, String propertyName)
     {
         String s;
         if (!getConfig().containsKey(propertyName))
@@ -4609,6 +4610,19 @@
             }
         }
     }
+    
+    private void loadPrefixFromDefaultIfNotDefined(Map configMap, Properties defaultProperties, String prefix)
+    {
+        Map<String, String> defaultPropsWithPrefix = Util.getDefaultPropertiesWithPrefix(defaultProperties, prefix);
+
+        for(String currentDefaultProperty: defaultPropsWithPrefix.keySet())
+        {
+            if(!configMap.containsKey(currentDefaultProperty))
+            {
+                configMap.put(currentDefaultProperty, defaultPropsWithPrefix.get(currentDefaultProperty));
+            }
+        }
+    }
 
     /**
      * Read the framework version from the property file.
diff --git a/framework/src/main/java/org/apache/felix/framework/util/FelixConstants.java b/framework/src/main/java/org/apache/felix/framework/util/FelixConstants.java
index 0a83c07..0f2b4a4 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/FelixConstants.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/FelixConstants.java
@@ -51,8 +51,8 @@
     String IMPLICIT_BOOT_DELEGATION_PROP = "felix.bootdelegation.implicit";
     String BOOT_CLASSLOADERS_PROP = "felix.bootdelegation.classloaders";
     String USE_LOCALURLS_PROP = "felix.jarurls";
-    String NATIVE_OS_NAME_ALIASES = "felix.native.osname.aliases";
-    String NATIVE_PROC_NAME_ALIASES = "felix.native.processor.aliases";
+    String NATIVE_OS_NAME_ALIAS_PREFIX = "felix.native.osname.alias";
+    String NATIVE_PROC_NAME_ALIAS_PREFIX = "felix.native.processor.alias";
 
     // Missing OSGi constant for resolution directive.
     String RESOLUTION_DYNAMIC = "dynamic";
diff --git a/framework/src/main/java/org/apache/felix/framework/util/Util.java b/framework/src/main/java/org/apache/felix/framework/util/Util.java
index ac9500b..8128aa1 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/Util.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/Util.java
@@ -20,7 +20,6 @@
 
 import java.io.*;
 import java.net.URL;
-
 import java.security.SecureRandom;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -29,11 +28,12 @@
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Properties;
+import java.util.Set;
+
 import org.apache.felix.framework.Logger;
 import org.apache.felix.framework.capabilityset.CapabilitySet;
 import org.apache.felix.framework.wiring.BundleCapabilityImpl;
 import org.apache.felix.framework.wiring.BundleRequirementImpl;
-
 import org.osgi.framework.Bundle;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
@@ -50,10 +50,9 @@
     **/
     private static final String DEFAULT_PROPERTIES_FILE = "default.properties";
 
-    public static String getDefaultProperty(Logger logger, String name)
+    public static Properties loadDefaultProperties(Logger logger)
     {
-        String value = null;
-
+        Properties defaultProperties = new Properties();
         URL propURL = Util.class.getClassLoader().getResource(DEFAULT_PROPERTIES_FILE);
         if (propURL != null)
         {
@@ -62,14 +61,8 @@
             {
                 // Load properties from URL.
                 is = propURL.openConnection().getInputStream();
-                Properties props = new Properties();
-                props.load(is);
+                defaultProperties.load(is);
                 is.close();
-                // Perform variable substitution for property.
-                value = props.getProperty(name);
-                value = (value != null)
-                    ? Util.substVars(value, name, null, props)
-                    : null;
             }
             catch (Exception ex)
             {
@@ -87,9 +80,51 @@
                     Logger.LOG_ERROR, "Unable to load any configuration properties.", ex);
             }
         }
+        return defaultProperties;
+    }
+
+    public static String getDefaultProperty(Logger logger, String name)
+    {
+        Properties props = loadDefaultProperties(logger);
+        // Perform variable substitution for property.
+        return getPropertyWithSubs(props, name);
+    }
+
+    public static String getPropertyWithSubs(Properties props, String name)
+    {
+        // Perform variable substitution for property.
+        String value = props.getProperty(name);
+        value = (value != null)
+            ? Util.substVars(value, name, null, props): null;
         return value;
     }
 
+    public static Map<String, String> getDefaultPropertiesWithPrefix(Logger logger, String prefix)
+    {
+        Properties props = loadDefaultProperties(logger);
+        return getDefaultPropertiesWithPrefix(props, prefix);
+    }
+
+    public static Map<String, String> getDefaultPropertiesWithPrefix(Properties props, String prefix)
+    {
+        Map<String, String> result = new HashMap<String, String>();
+
+        Set<String> propertySet = props.stringPropertyNames();
+
+        for(String currentPropertyKey: propertySet)
+        {
+            if(currentPropertyKey.startsWith(prefix))
+            {
+                String value = props.getProperty(currentPropertyKey);
+                // Perform variable substitution for property.
+                value = (value != null)
+                    ? Util.substVars(value, currentPropertyKey, null, props): null;
+                result.put(currentPropertyKey, value);
+            }
+        }
+        return result;
+    }
+
     /**
      * Converts a revision identifier to a bundle identifier. Revision IDs
      * are typically <tt>&lt;bundle-id&gt;.&lt;revision&gt;</tt>; this
diff --git a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/NativeLibraryClause.java b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/NativeLibraryClause.java
index 3f29384..92b30dd 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/NativeLibraryClause.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/NativeLibraryClause.java
@@ -91,45 +91,6 @@
 
     private static final Map<String, List<String>> PROC_ALIASES = new HashMap<String, List<String>>();
 
-    /* Storing the OS names in a map as this is quicker to look up than a list.
-     */
-    private static final Map<String, String> NORMALIZED_OS_NAMES;
-    static
-    {
-        Map<String, String> m = new HashMap<String, String>();
-        m.put(OS_AIX, "");
-        m.put(OS_DIGITALUNIX, "");
-        m.put(OS_EPOC, "");
-        m.put(OS_HPUX, "");
-        m.put(OS_IRIX, "");
-        m.put(OS_LINUX, "");
-        m.put(OS_MACOS, "");
-        m.put(OS_NETBSD, "");
-        m.put(OS_NETWARE, "");
-        m.put(OS_OPENBSD, "");
-        m.put(OS_OS2, "");
-        m.put(OS_QNX, "");
-        m.put(OS_SOLARIS, "");
-        m.put(OS_SUNOS, "");
-        m.put(OS_VXWORKS, "");
-        m.put(OS_WINDOWS_2000, "");
-        m.put(OS_WINDOWS_2003, "");
-        m.put(OS_WINDOWS_7, "");
-        m.put(OS_WINDOWS_8, "");
-        m.put(OS_WINDOWS_9, "");
-        m.put(OS_WINDOWS_95, "");
-        m.put(OS_WINDOWS_98, "");
-        m.put(OS_WINDOWS_CE, "");
-        m.put(OS_WINDOWS_NT, "");
-        m.put(OS_WINDOWS_SERVER_2008, "");
-        m.put(OS_WINDOWS_SERVER_2012, "");
-        m.put(OS_WINDOWS_VISTA, "");
-        m.put(OS_WINDOWS_XP, "");
-        m.put(OS_WIN_32, "");
-
-        NORMALIZED_OS_NAMES = Collections.unmodifiableMap(m);
-    }
-
     private final String[] m_libraryEntries;
     private final String[] m_osnames;
     private final String[] m_processors;
@@ -161,44 +122,82 @@
      * 
      * @param config
      */
-    public static synchronized void initializeNativeAliases(Map config)
+    public static synchronized void initializeNativeAliases(Map configMap)
     {
-        String osNameAlias = (String) config.get(FelixConstants.NATIVE_OS_NAME_ALIASES);
-        String processorAlias = (String) config.get(FelixConstants.NATIVE_PROC_NAME_ALIASES);
-        
-        parseNativeAliases(osNameAlias, OS_ALIASES);
-        parseNativeAliases(processorAlias, PROC_ALIASES);
+        Map<String, String> osNameKeyMap = getAllKeysWithPrefix(FelixConstants.NATIVE_OS_NAME_ALIAS_PREFIX, configMap);
+
+        Map<String, String> processorKeyMap = getAllKeysWithPrefix(FelixConstants.NATIVE_PROC_NAME_ALIAS_PREFIX, configMap);
+
+        parseNativeAliases(osNameKeyMap, OS_ALIASES);
+        parseNativeAliases(processorKeyMap, PROC_ALIASES);
     }
 
-    private static void parseNativeAliases(String aliasString, Map<String, List<String>> aliasMap)
+    private static void parseNativeAliases(Map<String, String> aliasStringMap, Map<String, List<String>> aliasMap)
     {
-        StringTokenizer tokenizer = new StringTokenizer(aliasString, ",");
-        
-        while(tokenizer.hasMoreTokens())
+        for(Map.Entry<String, String> aliasEntryString: aliasStringMap.entrySet())
         {
-            String currentItem = tokenizer.nextToken();
-            String[] aliases = currentItem.split("\\|");
-            for(String currentAlias: aliases)
+            String currentAliasKey = aliasEntryString.getKey();
+
+            String currentNormalizedName = currentAliasKey.substring(currentAliasKey.lastIndexOf(".")+1);
+
+            String currentAliasesString = aliasEntryString.getValue();
+
+            if(currentAliasesString != null)
             {
-                List<String> aliasList = aliasMap.get(currentAlias);
-                if(aliasList == null)
+                String[] aliases = currentAliasesString.split(",");
+                List<String> fullAliasList = new ArrayList<String>();
+                //normalized name is always first.
+                fullAliasList.add(currentNormalizedName);
+                fullAliasList.addAll(Arrays.asList(aliases));
+                aliasMap.put(currentNormalizedName, fullAliasList);
+                for(String currentAlias: aliases)
                 {
-                    aliasMap.put(currentAlias, new ArrayList<String>(Arrays.asList(aliases)));
-                }
-                else
-                {
-                    for(String newAliases: aliases)
+                    List<String> aliasList = aliasMap.get(currentAlias);
+                    if(aliasList == null)
                     {
-                        if(!aliasList.contains(newAliases))
+                        aliasMap.put(currentAlias, fullAliasList);
+                    }
+                    else
+                    {
+                        for(String newAliases: aliases)
                         {
-                            aliasList.add(newAliases);
+                            if(!aliasList.contains(newAliases))
+                            {
+                                aliasList.add(newAliases);
+                            }
                         }
                     }
                 }
             }
+            else
+            {
+                List<String> aliasList = aliasMap.get(currentNormalizedName);
+                if(aliasList == null)
+                {
+                    aliasMap.put(currentNormalizedName, new ArrayList<String>(Collections.singletonList(currentNormalizedName)));
+                }
+                else
+                {
+                    //if the alias is also a normalized name make sure it's first
+                    aliasList.add(0, currentNormalizedName);
+                }
+            }
         }
     }
 
+    private static Map<String, String> getAllKeysWithPrefix(String prefix, Map<String, String> configMap)
+    {
+        Map<String, String> keysWithPrefix = new HashMap<String, String>();
+        for(Map.Entry<String, String> currentEntry: configMap.entrySet())
+        {
+            if(currentEntry.getKey().startsWith(prefix))
+            {
+                keysWithPrefix.put(currentEntry.getKey(), currentEntry.getValue());
+            }
+        }
+        return keysWithPrefix;
+    }
+
     public String[] getLibraryEntries()
     {
         return m_libraryEntries;
@@ -543,17 +542,18 @@
         }
         return Collections.unmodifiableList(result);
     }
-    
+
     public static String normalizeOSName(String value)
     {
-        if (NORMALIZED_OS_NAMES.containsKey(value))
-        {
-            // Already normalized
-            return value;
-        }
-
         value = value.toLowerCase();
 
+        if (OS_ALIASES.containsKey(value))
+        {
+            // we found an alias match return the first value which is the normalized name
+            return OS_ALIASES.get(value).get(0);
+        }
+
+        //If we don't find a match do it the old way for compatibility
         if (value.startsWith("win"))
         {
             String os = "win";
@@ -682,6 +682,11 @@
     {
         value = value.toLowerCase();
 
+        if(PROC_ALIASES.containsKey(value))
+        {
+            return PROC_ALIASES.get(value).get(0);
+        }
+
         if (value.startsWith(PROC_X86_64) || value.startsWith("amd64") ||
             value.startsWith("em64") || value.startsWith("x86_64"))
         {
diff --git a/framework/src/main/resources/default.properties b/framework/src/main/resources/default.properties
index f9b898a..7ebb231 100644
--- a/framework/src/main/resources/default.properties
+++ b/framework/src/main/resources/default.properties
@@ -24,16 +24,49 @@
  ${dollar}{eecap-${dollar}{java.specification.version}}
  
 # Native Processor Aliases.  Comma delimits processors.  Pipe delimits processor aliases.
-felix.native.processor.aliases=ignite|psc1k,powerpc|power|ppc,x86|pentium|i386|i486|i586|i686, \
- x86-64|amd64|em64t|x86_64
+felix.native.processor.alias.68k=
+felix.native.processor.alias.arm=
+felix.native.processor.alias.arm_le=
+felix.native.processor.alias.arm_be=
+felix.native.processor.alias.alpha=
+felix.native.processor.alias.ignite=psc1k
+felix.native.processor.alias.mips=
+felix.native.processor.alias.parisc=
+felix.native.processor.alias.powerpc=power,ppc
+felix.native.processor.alias.x86=pentium,i386,i486,i586,i686
+felix.native.processor.alias.x86-64=amd64,em64t,x86_64
+felix.native.processor.alias.sparc=
 
 # Native Operating System Name Aliases.  Comma delimits Operating System Names.  Pipe delimits Operating System Aliases.
-felix.native.osname.aliases=epoc32|symbianos,hpux|hp-ux,macos|mac os,macosx|mac os x, \
- os2|os/2,qnx|procnto,windows95|win95|windows 95|win32,windows98|win98|windows 98|win32, \
- windowsnt|winnt|windows nt|win32,windowsce|wince|windows ce,windows2000|win2000|windows 2000|win32, \
- windows2003|win2003|windows 2003|win32|windows server 2003,windowsxp|winxp|windows xp|win32, \
- windowsvista|winvista|windows vista|win32,windows7|windows 7|win32,windows8|windows 8|win32, \
- windows9|windows 9|win32,windowsserver2008|windows server 2008|win32
+felix.native.osname.alias.aix=
+felix.native.osname.alias.digitalunix=
+felix.native.osname.alias.epoc32=symbianos
+felix.native.osname.alias.hpux=hp-ux
+felix.native.osname.alias.irix=
+felix.native.osname.alias.linux=
+felix.native.osname.alias.macos=mac os
+felix.native.osname.alias.macosx=mac os x
+felix.native.osname.alias.netbsd=
+felix.native.osname.alias.netware=
+felix.native.osname.alias.openbsd=
+felix.native.osname.alias.os2=os/2
+felix.native.osname.alias.qnx=procnto
+felix.native.osname.alias.solaris=
+felix.native.osname.alias.sunos=
+felix.native.osname.alias.vxworks=
+felix.native.osname.alias.windows95=win95,windows 95,win32
+felix.native.osname.alias.windows98=win98,windows 98,win32
+felix.native.osname.alias.windowsnt=winnt,windows nt,win32
+felix.native.osname.alias.windowsce=wince,windows ce
+felix.native.osname.alias.windows2000=win2000,windows 2000,win32
+felix.native.osname.alias.windows2003=win2003,windows 2003,win32,windows server 2003
+felix.native.osname.alias.windowsxp=winxp,windows xp,win32
+felix.native.osname.alias.windowsvista=winvista,windows vista,win32
+felix.native.osname.alias.windows7=windows 7,win32
+felix.native.osname.alias.windows8=windows 8,win32
+felix.native.osname.alias.windows9=windows 9,win32
+felix.native.osname.alias.windowsserver2008=windows server 2008,win32
+felix.native.osname.alias.win32=
 
 eecap-1.8= osgi.ee; osgi.ee="OSGi/Minimum"; version:List<Version>="1.0,1.1,1.2", \
  osgi.ee; osgi.ee="JavaSE"; version:List<Version>="1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8", \
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 54f1d4d..c59910f 100644
--- a/framework/src/test/java/org/apache/felix/framework/ExtensionManagerTest.java
+++ b/framework/src/test/java/org/apache/felix/framework/ExtensionManagerTest.java
@@ -82,8 +82,8 @@
         configMap.put(FelixConstants.FRAMEWORK_PROCESSOR, "x86_64");
         configMap.put(FelixConstants.FRAMEWORK_OS_NAME, "windows8");
         configMap.put(FelixConstants.FRAMEWORK_OS_VERSION, "6.3");
-        configMap.put(FelixConstants.NATIVE_OS_NAME_ALIASES, "windows8|windows 8|win32");
-        configMap.put(FelixConstants.NATIVE_PROC_NAME_ALIASES, "x86-64|amd64|em64t|x86_64");
+        configMap.put(FelixConstants.NATIVE_OS_NAME_ALIAS_PREFIX + ".windows8", "windows 8,win32");
+        configMap.put(FelixConstants.NATIVE_PROC_NAME_ALIAS_PREFIX + ".x86-64", "amd64,em64t,x86_64");
         NativeLibraryClause.initializeNativeAliases(configMap);
         ExtensionManager extensionManager = new ExtensionManager(logger,
                 configMap, null);