FELIX-4757 Allow felix processor and os name aliases to be loaded from config and default properties files

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1650058 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 6400074..e533fde 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -402,6 +402,9 @@
             m_bootPkgs[i] = s;
         }
 
+        //Initialize Native Library Aliases
+        NativeLibraryClause.initializeNativeAliases(m_configMap);
+
         // Read the security default policy property
         m_securityDefaultPolicy = "true".equals(getProperty(FelixConstants.SECURITY_DEFAULT_POLICY));
 
@@ -4561,14 +4564,23 @@
 
         // Set supported execution environments to default value,
         // if not explicitly configured.
-        if (!getConfig().containsKey(Constants.FRAMEWORK_EXECUTIONENVIRONMENT))
+        loadFromDefaultIfNotDefined(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);
+    }
+
+    private void loadFromDefaultIfNotDefined(String propertyName)
+    {
+        String s;
+        if (!getConfig().containsKey(propertyName))
         {
-            s = Util.getDefaultProperty(
-                m_logger, Constants.FRAMEWORK_EXECUTIONENVIRONMENT);
+            s = Util.getDefaultProperty(m_logger, propertyName);
             if (s != null)
             {
-                m_configMutableMap.put(
-                    Constants.FRAMEWORK_EXECUTIONENVIRONMENT, s);
+                m_configMutableMap.put(propertyName, s);
             }
         }
     }
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 a48de4b..0a83c07 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,6 +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";
 
     // Missing OSGi constant for resolution directive.
     String RESOLUTION_DYNAMIC = "dynamic";
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 5c46f0e..3f29384 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
@@ -23,12 +23,10 @@
 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;
@@ -88,6 +86,11 @@
     private static final String PROC_POWER_PC = "powerpc";
     private static final String PROC_SPARC = "sparc";
 
+
+    private static final Map<String, List<String>> OS_ALIASES = new HashMap<String, List<String>>();
+
+    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;
@@ -96,6 +99,7 @@
         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, "");
@@ -152,6 +156,49 @@
             library.m_selectionFilter);
     }
 
+    /**
+     * Initialize the processor and os name aliases from Felix Config.
+     * 
+     * @param config
+     */
+    public static synchronized void initializeNativeAliases(Map config)
+    {
+        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);
+    }
+
+    private static void parseNativeAliases(String aliasString, Map<String, List<String>> aliasMap)
+    {
+        StringTokenizer tokenizer = new StringTokenizer(aliasString, ",");
+        
+        while(tokenizer.hasMoreTokens())
+        {
+            String currentItem = tokenizer.nextToken();
+            String[] aliases = currentItem.split("\\|");
+            for(String currentAlias: aliases)
+            {
+                List<String> aliasList = aliasMap.get(currentAlias);
+                if(aliasList == null)
+                {
+                    aliasMap.put(currentAlias, new ArrayList<String>(Arrays.asList(aliases)));
+                }
+                else
+                {
+                    for(String newAliases: aliases)
+                    {
+                        if(!aliasList.contains(newAliases))
+                        {
+                            aliasList.add(newAliases);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     public String[] getLibraryEntries()
     {
         return m_libraryEntries;
@@ -473,168 +520,9 @@
         //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>();
+        List<String> result = OS_ALIASES.get(osName);
 
-                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
+        if(result == null)
         {
             result = Collections.singletonList(osName);
         }
@@ -647,45 +535,9 @@
         //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
+        List<String> result = PROC_ALIASES.get(processor);
+
+        if(result == null)
         {
             result = Collections.singletonList(processor);
         }
diff --git a/framework/src/main/resources/default.properties b/framework/src/main/resources/default.properties
index 5ef3625..f9b898a 100644
--- a/framework/src/main/resources/default.properties
+++ b/framework/src/main/resources/default.properties
@@ -22,6 +22,18 @@
 # New-style generic execution environment capabilities.
 org.osgi.framework.system.capabilities= \
  ${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
+
+# 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
 
 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 a281562..54f1d4d 100644
--- a/framework/src/test/java/org/apache/felix/framework/ExtensionManagerTest.java
+++ b/framework/src/test/java/org/apache/felix/framework/ExtensionManagerTest.java
@@ -19,6 +19,7 @@
 package org.apache.felix.framework;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import java.io.File;
 import java.io.FileOutputStream;
@@ -28,12 +29,14 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.jar.JarOutputStream;
 import java.util.jar.Manifest;
 import java.util.zip.ZipEntry;
 
 import org.apache.felix.framework.util.FelixConstants;
+import org.apache.felix.framework.util.manifestparser.NativeLibraryClause;
 import org.junit.Before;
 import org.junit.Test;
 import org.osgi.framework.BundleActivator;
@@ -79,6 +82,9 @@
         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");
+        NativeLibraryClause.initializeNativeAliases(configMap);
         ExtensionManager extensionManager = new ExtensionManager(logger,
                 configMap, null);
         BundleCapability nativeBundleCapability = extensionManager
@@ -88,16 +94,16 @@
                 "en",
                 nativeBundleCapability.getAttributes().get(
                         NativeNamespace.CAPABILITY_LANGUAGE_ATTRIBUTE));
-        assertEquals(
+        assertTrue(
                 "Native Processor should be same as framework Processor",
-                Arrays.asList("x86-64", "amd64", "em64t", "x86_64"),
+                Arrays.asList("x86-64", "amd64", "em64t", "x86_64").containsAll((List)
                 nativeBundleCapability.getAttributes().get(
-                        NativeNamespace.CAPABILITY_PROCESSOR_ATTRIBUTE));
-        assertEquals(
+                        NativeNamespace.CAPABILITY_PROCESSOR_ATTRIBUTE)));
+        assertTrue(
                 "Native OS Name should be the same as the framework os name",
-                Arrays.asList("windows8", "windows 8", "win32"),
+                Arrays.asList("windows8", "windows 8", "win32").containsAll((List)
                 nativeBundleCapability.getAttributes().get(
-                        NativeNamespace.CAPABILITY_OSNAME_ATTRIBUTE));
+                        NativeNamespace.CAPABILITY_OSNAME_ATTRIBUTE)));
         assertEquals(
                 "Native OS Version should be the same as the framework OS Version",
                 new Version("6.3"),