Look in fragments for native libraries. (FELIX-1134)


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@793684 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java b/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
index 47ab08a..277088b 100644
--- a/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
@@ -334,9 +334,23 @@
         return (IRequirement[]) reqList.toArray(new IRequirement[reqList.size()]);
     }
 
-    public R4Library[] getNativeLibraries()
+    public synchronized R4Library[] getNativeLibraries()
     {
-        return m_nativeLibraries;
+        List nativeList = (m_nativeLibraries == null)
+            ? new ArrayList() : new ArrayList(Arrays.asList(m_nativeLibraries));
+        for (int fragIdx = 0;
+            (m_fragments != null) && (fragIdx < m_fragments.length);
+            fragIdx++)
+        {
+            R4Library[] libs = m_fragments[fragIdx].getNativeLibraries();
+            for (int reqIdx = 0;
+                (libs != null) && (reqIdx < libs.length);
+                reqIdx++)
+            {
+                nativeList.add(libs[reqIdx]);
+            }
+        }
+        return (R4Library[]) nativeList.toArray(new R4Library[nativeList.size()]);
     }
 
     public int getDeclaredActivationPolicy()
@@ -1567,7 +1581,7 @@
     public class ModuleClassLoader extends SecureClassLoader implements BundleReference
     {
         private final Map m_jarContentToDexFile;
-        private Object[][] m_libs = new Object[0][];
+        private Object[][] m_cachedLibs = new Object[0][];
         private static final int LIBNAME_IDX = 0;
         private static final int LIBPATH_IDX = 1;
 
@@ -1892,11 +1906,11 @@
             synchronized (this)
             {
                 // Check to make sure we haven't already found this library.
-                for (int i = 0; (result == null) && (i < m_libs.length); i++)
+                for (int i = 0; (result == null) && (i < m_cachedLibs.length); i++)
                 {
-                    if (m_libs[i][LIBNAME_IDX].equals(name))
+                    if (m_cachedLibs[i][LIBNAME_IDX].equals(name))
                     {
-                        result = (String) m_libs[i][LIBPATH_IDX];
+                        result = (String) m_cachedLibs[i][LIBPATH_IDX];
                     }
                 }
 
@@ -1905,21 +1919,32 @@
                 if (result == null)
                 {
                     R4Library[] libs = getNativeLibraries();
-                    for (int i = 0; (libs != null) && (i < libs.length); i++)
+                    for (int libIdx = 0; (libs != null) && (libIdx < libs.length); libIdx++)
                     {
-                        if (libs[i].match(m_configMap, name))
+                        if (libs[libIdx].match(m_configMap, name))
                         {
-                            result = getContent().getEntryAsNativeLibrary(libs[i].getEntryName());
+                            // Search bundle content first for native library.
+                            result = getContent().getEntryAsNativeLibrary(
+                                libs[libIdx].getEntryName());
+                            // If not found, then search fragments in order.
+                            for (int i = 0;
+                                (result == null) && (m_fragmentContents != null)
+                                    && (i < m_fragmentContents.length);
+                                i++)
+                            {
+                                result = m_fragmentContents[i].getEntryAsNativeLibrary(
+                                    libs[libIdx].getEntryName());
+                            }
                         }
                     }
 
                     // Remember the result for future requests.
                     if (result != null)
                     {
-                        Object[][] tmp = new Object[m_libs.length + 1][];
-                        System.arraycopy(m_libs, 0, tmp, 0, m_libs.length);
-                        tmp[m_libs.length] = new Object[] { name, result };
-                        m_libs = tmp;
+                        Object[][] tmp = new Object[m_cachedLibs.length + 1][];
+                        System.arraycopy(m_cachedLibs, 0, tmp, 0, m_cachedLibs.length);
+                        tmp[m_cachedLibs.length] = new Object[] { name, result };
+                        m_cachedLibs = tmp;
                     }
                 }
             }
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 4892c50..6131ea3 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
@@ -52,11 +52,6 @@
         = "felix.startlevel.bundle";
     public static final String SERVICE_URLHANDLERS_PROP = "felix.service.urlhandlers";
 
-    // THESE CAN BE DELETED ONCE WE HAVE COMPLETE FRAGMENT SUPPORT.
-    public static final String FRAGMENT_VALIDATION_PROP = "felix.fragment.validation";
-    public static final String FRAGMENT_VALIDATION_EXCEPTION_VALUE = "exception";
-    public static final String FRAGMENT_VALIDATION_WARNING_VALUE = "warning";
-
     // Start level-related constants.
     public static final int FRAMEWORK_INACTIVE_STARTLEVEL = 0;
     public static final int FRAMEWORK_DEFAULT_STARTLEVEL = 1;
@@ -66,4 +61,4 @@
     // Miscellaneous properties values.
     public static final String FAKE_URL_PROTOCOL_VALUE = "location:";
     public static final String FELIX_EXTENSION_ACTIVATOR = "Felix-Activator";
-}
+}
\ No newline at end of file
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 cce6f45..548f51f 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
@@ -121,7 +121,6 @@
             (String) headerMap.get(Constants.FRAGMENT_HOST));
         if (clauses.length > 0)
         {
-            validateFragment(headerMap);
             try
             {
                 reqList.add(
@@ -272,38 +271,6 @@
         }
     }
 
-    /**
-     * Checks whether a fragment uses features that we do not currently support
-     * (e.g., Import-Package, Export-Package, and Bundle-NativeCode). If so, we
-     * throw an exception.
-     * @param headerMap the header to validate.
-    **/
-    private void validateFragment(Map headerMap) throws BundleException
-    {
-        // TODO: FRAGMENTS - We should delete this method and the related
-        //       fragment constants in FelixConstants when fragments are
-        //       fully implemented.
-        String fragmentHost = (String) headerMap.get(Constants.FRAGMENT_HOST);
-        if ((fragmentHost != null) && (parseExtensionBundleHeader(fragmentHost) == null))
-        {
-            if (headerMap.get(Constants.BUNDLE_NATIVECODE) != null)
-            {
-                String s = (String) m_configMap.get(FelixConstants.FRAGMENT_VALIDATION_PROP);
-                s = (s == null) ? FelixConstants.FRAGMENT_VALIDATION_EXCEPTION_VALUE : s;
-                if (s.equalsIgnoreCase(FelixConstants.FRAGMENT_VALIDATION_WARNING_VALUE))
-                {
-                    m_logger.log(Logger.LOG_WARNING,
-                        "Fragments with native code are not currently supported.");
-                }
-                else
-                {
-                    throw new BundleException(
-                        "Fragments native code are not currently supported.");
-                }
-            }
-        }
-    }
-
     public String getManifestVersion()
     {
         String manifestVersion = (String) m_headerMap.get(Constants.BUNDLE_MANIFESTVERSION);
diff --git a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/R4Library.java b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/R4Library.java
index e47ffc4..a28c34c 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/R4Library.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/R4Library.java
@@ -125,37 +125,42 @@
         {
             StringBuffer sb = new StringBuffer();
             sb.append(m_libraryFile);
-            sb.append(';');
             for (int i = 0; (m_osnames != null) && (i < m_osnames.length); i++)
             {
+                sb.append(';');
                 sb.append(Constants.BUNDLE_NATIVECODE_OSNAME);
                 sb.append('=');
                 sb.append(m_osnames[i]);
-                sb.append(';');
             }
             for (int i = 0; (m_processors != null) && (i < m_processors.length); i++)
             {
-                sb.append(Constants.BUNDLE_NATIVECODE_PROCESSOR);
-                sb.append(m_processors[i]);
                 sb.append(';');
+                sb.append(Constants.BUNDLE_NATIVECODE_PROCESSOR);
+                sb.append('=');
+                sb.append(m_processors[i]);
             }
             for (int i = 0; (m_osversions != null) && (i < m_osversions.length); i++)
             {
-                sb.append(Constants.BUNDLE_NATIVECODE_OSVERSION);
-                sb.append(m_osversions[i]);
                 sb.append(';');
+                sb.append(Constants.BUNDLE_NATIVECODE_OSVERSION);
+                sb.append('=');
+                sb.append(m_osversions[i]);
             }
             for (int i = 0; (m_languages != null) && (i < m_languages.length); i++)
             {
-                sb.append(Constants.BUNDLE_NATIVECODE_LANGUAGE);
-                sb.append(m_languages[i]);
                 sb.append(';');
+                sb.append(Constants.BUNDLE_NATIVECODE_LANGUAGE);
+                sb.append('=');
+                sb.append(m_languages[i]);
             }
-            sb.append(Constants.SELECTION_FILTER_ATTRIBUTE);
-            sb.append('=');
-            sb.append('\'');
-            sb.append(m_selectionFilter);
-            sb.append('\'');
+            if (m_selectionFilter != null)
+            {
+                sb.append(';');
+                sb.append(Constants.SELECTION_FILTER_ATTRIBUTE);
+                sb.append('=');
+                sb.append('\'');
+                sb.append(m_selectionFilter);
+            }
 
             return sb.toString();
         }