You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ri...@apache.org on 2009/06/12 22:21:59 UTC

svn commit: r784258 - in /felix/trunk/framework/src/main/java/org/apache/felix/framework: Felix.java ModuleImpl.java util/Util.java util/manifestparser/Capability.java util/manifestparser/ManifestParser.java

Author: rickhall
Date: Fri Jun 12 20:21:59 2009
New Revision: 784258

URL: http://svn.apache.org/viewvc?rev=784258&view=rev
Log:
Implement include/exclude directives for activation policy. (FELIX-749)

Modified:
    felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java
    felix/trunk/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
    felix/trunk/framework/src/main/java/org/apache/felix/framework/util/Util.java
    felix/trunk/framework/src/main/java/org/apache/felix/framework/util/manifestparser/Capability.java
    felix/trunk/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java?rev=784258&r1=784257&r2=784258&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java Fri Jun 12 20:21:59 2009
@@ -1518,7 +1518,7 @@
             // been triggered, then activate the bundle immediately.
             if (!bundle.isDeclaredActivationPolicyUsed()
                 || (bundle.getCurrentModule().getDeclaredActivationPolicy() != IModule.LAZY_ACTIVATION)
-                || ((ModuleImpl) bundle.getCurrentModule()).isActivationTrigger())
+                || ((ModuleImpl) bundle.getCurrentModule()).isActivationTriggered())
             {
                 // Record the event type for the final event and activate.
                 eventType = BundleEvent.STARTED;

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java?rev=784258&r1=784257&r2=784258&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java Fri Jun 12 20:21:59 2009
@@ -78,6 +78,9 @@
     private final IRequirement[] m_dynamicRequirements;
     private final R4Library[] m_nativeLibraries;
     private final int m_declaredActivationPolicy;
+    private final String[] m_activationIncludes;
+    private final String[] m_activationExcludes;
+
     private final Bundle m_bundle;
 
     private IModule[] m_fragments = null;
@@ -140,6 +143,8 @@
         m_dynamicRequirements = null;
         m_nativeLibraries = null;
         m_declaredActivationPolicy = EAGER_ACTIVATION;
+        m_activationExcludes = null;
+        m_activationIncludes = null;
     }
 
     public ModuleImpl(
@@ -172,6 +177,12 @@
         m_dynamicRequirements = mp.getDynamicRequirements();
         m_nativeLibraries = mp.getLibraries();
         m_declaredActivationPolicy = mp.getActivationPolicy();
+        m_activationExcludes = (mp.getActivationExcludeDirective() == null)
+            ? null
+            : ManifestParser.parseDelimitedString(mp.getActivationExcludeDirective(), ",");
+        m_activationIncludes = (mp.getActivationIncludeDirective() == null)
+            ? null
+            : ManifestParser.parseDelimitedString(mp.getActivationIncludeDirective(), ",");
         m_symbolicName = mp.getSymbolicName();
         m_isExtension = mp.isExtension();
 
@@ -311,6 +322,40 @@
         return m_declaredActivationPolicy;
     }
 
+    synchronized boolean isActivationTriggered()
+    {
+        return m_isActivationTriggered;
+    }
+
+    boolean isActivationTrigger(String pkgName)
+    {
+        if ((m_activationIncludes == null) && (m_activationExcludes == null))
+        {
+            return true;
+        }
+
+        // If there are no include filters then all classes are included
+        // by default, otherwise try to find one match.
+        boolean included = (m_activationIncludes == null);
+        for (int i = 0;
+            (!included) && (m_activationIncludes != null) && (i < m_activationIncludes.length);
+            i++)
+        {
+            included = m_activationIncludes[i].equals(pkgName);
+        }
+
+        // If there are no exclude filters then no classes are excluded
+        // by default, otherwise try to find one match.
+        boolean excluded = false;
+        for (int i = 0;
+            (!excluded) && (m_activationExcludes != null) && (i < m_activationExcludes.length);
+            i++)
+        {
+            excluded = m_activationExcludes[i].equals(pkgName);
+        }
+        return included && !excluded;
+    }
+
     //
     // Run-time data access.
     //
@@ -1178,11 +1223,6 @@
         return m_id;
     }
 
-    synchronized boolean isActivationTrigger()
-    {
-        return m_isActivationTriggered;
-    }
-
     private synchronized ModuleClassLoader getClassLoader()
     {
         if (m_classLoader == null)
@@ -1543,6 +1583,9 @@
 
                 if (bytes != null)
                 {
+                    // Get package name.
+                    String pkgName = Util.getClassPackage(name);
+
                     // Before we actually attempt to define the class, grab
                     // the lock for this class loader and make sure than no
                     // other thread has defined this class in the meantime.
@@ -1559,8 +1602,13 @@
 
                             // If the module is using deferred activation, then if
                             // we load this class from this module we need to activate
-                            // the module before returning the class.
+                            // the module before returning the class. We will short
+                            // circuit the trigger matching if the trigger is already
+                            // tripped.
+                            boolean isTriggerClass = m_isActivationTriggered
+                                ? false : isActivationTrigger(pkgName);
                             if (!m_isActivationTriggered
+                                && isTriggerClass
                                 && (activationPolicy == IModule.LAZY_ACTIVATION)
                                 && (getBundle().getState() == Bundle.STARTING))
                             {
@@ -1573,9 +1621,8 @@
                                 deferredList.add(new Object[] { name, getBundle() });
                             }
                             // We need to try to define a Package object for the class
-                            // before we call defineClass(). Get the package name and
-                            // see if we have already created the package.
-                            String pkgName = Util.getClassPackage(name);
+                            // before we call defineClass() if we haven't already
+                            // created it.
                             if (pkgName.length() > 0)
                             {
                                 if (getPackage(pkgName) == null)
@@ -1630,9 +1677,9 @@
                                 }
                             }
 
-                            // At this point if we have a class, then the deferred
+                            // At this point if we have a trigger class, then the deferred
                             // activation trigger has tripped.
-                            if (!m_isActivationTriggered && (clazz != null))
+                            if (!m_isActivationTriggered && isTriggerClass && (clazz != null))
                             {
                                 m_isActivationTriggered = true;
                             }

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/util/Util.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/util/Util.java?rev=784258&r1=784257&r2=784258&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/util/Util.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/util/Util.java Fri Jun 12 20:21:59 2009
@@ -527,4 +527,142 @@
         Map headerMap = module.getHeaders();
         return headerMap.containsKey(Constants.FRAGMENT_HOST);
     }
+
+
+    //
+    // The following substring-related code was lifted and modified
+    // from the LDAP parser code.
+    //
+
+    public static String[] parseSubstring(String target)
+    {
+        List pieces = new ArrayList();
+        StringBuffer ss = new StringBuffer();
+        // int kind = SIMPLE; // assume until proven otherwise
+        boolean wasStar = false; // indicates last piece was a star
+        boolean leftstar = false; // track if the initial piece is a star
+        boolean rightstar = false; // track if the final piece is a star
+
+        int idx = 0;
+
+        // We assume (sub)strings can contain leading and trailing blanks
+loop:   for (;;)
+        {
+            if (idx >= target.length())
+            {
+                if (wasStar)
+                {
+                    // insert last piece as "" to handle trailing star
+                    rightstar = true;
+                }
+                else
+                {
+                    pieces.add(ss.toString());
+                    // accumulate the last piece
+                    // note that in the case of
+                    // (cn=); this might be
+                    // the string "" (!=null)
+                }
+                ss.setLength(0);
+                break loop;
+            }
+
+            char c = target.charAt(idx++);
+            if (c == '*')
+            {
+                if (wasStar)
+                {
+                    // encountered two successive stars;
+                    // I assume this is illegal
+                    throw new IllegalArgumentException("Invalid filter string: " + target);
+                }
+                if (ss.length() > 0)
+                {
+                    pieces.add(ss.toString()); // accumulate the pieces
+                    // between '*' occurrences
+                }
+                ss.setLength(0);
+                // if this is a leading star, then track it
+                if (pieces.size() == 0)
+                {
+                    leftstar = true;
+                }
+                ss.setLength(0);
+                wasStar = true;
+            }
+            else
+            {
+                wasStar = false;
+                ss.append(c);
+            }
+        }
+        if (leftstar || rightstar || pieces.size() > 1)
+        {
+            // insert leading and/or trailing "" to anchor ends
+            if (rightstar)
+            {
+                pieces.add("");
+            }
+            if (leftstar)
+            {
+                pieces.add(0, "");
+            }
+        }
+        return (String[]) pieces.toArray(new String[pieces.size()]);
+    }
+
+    public static boolean checkSubstring(String[] pieces, String s)
+    {
+        // Walk the pieces to match the string
+        // There are implicit stars between each piece,
+        // and the first and last pieces might be "" to anchor the match.
+        // assert (pieces.length > 1)
+        // minimal case is <string>*<string>
+
+        boolean result = false;
+        int len = pieces.length;
+
+loop:   for (int i = 0; i < len; i++)
+        {
+            String piece = pieces[i];
+            int index = 0;
+            if (i == len - 1)
+            {
+                // this is the last piece
+                if (s.endsWith(piece))
+                {
+                    result = true;
+                }
+                else
+                {
+                    result = false;
+                }
+                break loop;
+            }
+            // initial non-star; assert index == 0
+            else if (i == 0)
+            {
+                if (!s.startsWith(piece))
+                {
+                    result = false;
+                    break loop;
+                }
+            }
+            // assert i > 0 && i < len-1
+            else
+            {
+                // Sure wish stringbuffer supported e.g. indexOf
+                index = s.indexOf(piece, index);
+                if (index < 0)
+                {
+                    result = false;
+                    break loop;
+                }
+            }
+            // start beyond the matching piece
+            index += piece.length();
+        }
+
+        return result;
+    }
 }
\ No newline at end of file

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/util/manifestparser/Capability.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/util/manifestparser/Capability.java?rev=784258&r1=784257&r2=784258&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/util/manifestparser/Capability.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/util/manifestparser/Capability.java Fri Jun 12 20:21:59 2009
@@ -69,7 +69,7 @@
                 m_includeFilter = new String[ss.length][];
                 for (int filterIdx = 0; filterIdx < ss.length; filterIdx++)
                 {
-                    m_includeFilter[filterIdx] = parseSubstring(ss[filterIdx]);
+                    m_includeFilter[filterIdx] = Util.parseSubstring(ss[filterIdx]);
                 }
             }
             else if (m_directives[dirIdx].getName().equals(Constants.EXCLUDE_DIRECTIVE))
@@ -78,7 +78,7 @@
                 m_excludeFilter = new String[ss.length][];
                 for (int filterIdx = 0; filterIdx < ss.length; filterIdx++)
                 {
-                    m_excludeFilter[filterIdx] = parseSubstring(ss[filterIdx]);
+                    m_excludeFilter[filterIdx] = Util.parseSubstring(ss[filterIdx]);
                 }
             }
         }
@@ -177,7 +177,7 @@
             (!included) && (m_includeFilter != null) && (i < m_includeFilter.length);
             i++)
         {
-            included = checkSubstring(m_includeFilter[i], className);
+            included = Util.checkSubstring(m_includeFilter[i], className);
         }
 
         // If there are no exclude filters then no classes are excluded
@@ -187,7 +187,7 @@
             (!excluded) && (m_excludeFilter != null) && (i < m_excludeFilter.length);
             i++)
         {
-            excluded = checkSubstring(m_excludeFilter[i], className);
+            excluded = Util.checkSubstring(m_excludeFilter[i], className);
         }
         return included && !excluded;
     }
@@ -335,141 +335,4 @@
         }
         return sb.toString();
     }
-
-    //
-    // The following substring-related code was lifted and modified
-    // from the LDAP parser code.
-    //
-
-    private static String[] parseSubstring(String target)
-    {
-        List pieces = new ArrayList();
-        StringBuffer ss = new StringBuffer();
-        // int kind = SIMPLE; // assume until proven otherwise
-        boolean wasStar = false; // indicates last piece was a star
-        boolean leftstar = false; // track if the initial piece is a star
-        boolean rightstar = false; // track if the final piece is a star
-
-        int idx = 0;
-
-        // We assume (sub)strings can contain leading and trailing blanks
-loop:   for (;;)
-        {
-            if (idx >= target.length())
-            {
-                if (wasStar)
-                {
-                    // insert last piece as "" to handle trailing star
-                    rightstar = true;
-                }
-                else
-                {
-                    pieces.add(ss.toString());
-                    // accumulate the last piece
-                    // note that in the case of
-                    // (cn=); this might be
-                    // the string "" (!=null)
-                }
-                ss.setLength(0);
-                break loop;
-            }
-
-            char c = target.charAt(idx++);
-            if (c == '*')
-            {
-                if (wasStar)
-                {
-                    // encountered two successive stars;
-                    // I assume this is illegal
-                    throw new IllegalArgumentException("Invalid filter string: " + target);
-                }
-                if (ss.length() > 0)
-                {
-                    pieces.add(ss.toString()); // accumulate the pieces
-                    // between '*' occurrences
-                }
-                ss.setLength(0);
-                // if this is a leading star, then track it
-                if (pieces.size() == 0)
-                {
-                    leftstar = true;
-                }
-                ss.setLength(0);
-                wasStar = true;
-            }
-            else
-            {
-                wasStar = false;
-                ss.append(c);
-            }
-        }
-        if (leftstar || rightstar || pieces.size() > 1)
-        {
-            // insert leading and/or trailing "" to anchor ends
-            if (rightstar)
-            {
-                pieces.add("");
-            }
-            if (leftstar)
-            {
-                pieces.add(0, "");
-            }
-        }
-        return (String[]) pieces.toArray(new String[pieces.size()]);
-    }
-
-    private static boolean checkSubstring(String[] pieces, String s)
-    {
-        // Walk the pieces to match the string
-        // There are implicit stars between each piece,
-        // and the first and last pieces might be "" to anchor the match.
-        // assert (pieces.length > 1)
-        // minimal case is <string>*<string>
-
-        boolean result = false;
-        int len = pieces.length;
-
-loop:   for (int i = 0; i < len; i++)
-        {
-            String piece = pieces[i];
-            int index = 0;
-            if (i == len - 1)
-            {
-                // this is the last piece
-                if (s.endsWith(piece))
-                {
-                    result = true;
-                }
-                else
-                {
-                    result = false;
-                }
-                break loop;
-            }
-            // initial non-star; assert index == 0
-            else if (i == 0)
-            {
-                if (!s.startsWith(piece))
-                {
-                    result = false;
-                    break loop;
-                }
-            }
-            // assert i > 0 && i < len-1
-            else
-            {
-                // Sure wish stringbuffer supported e.g. indexOf
-                index = s.indexOf(piece, index);
-                if (index < 0)
-                {
-                    result = false;
-                    break loop;
-                }
-            }
-            // start beyond the matching piece
-            index += piece.length();
-        }
-
-        return result;
-    }
 }
\ No newline at end of file

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java?rev=784258&r1=784257&r2=784258&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java Fri Jun 12 20:21:59 2009
@@ -34,6 +34,8 @@
     private final Map m_configMap;
     private final Map m_headerMap;
     private volatile int m_activationPolicy = IModule.EAGER_ACTIVATION;
+    private volatile String m_activationIncludeDir;
+    private volatile String m_activationExcludeDir;
     private volatile boolean m_isExtension = false;
     private volatile String m_bundleSymbolicName;
     private volatile Version m_bundleVersion;
@@ -255,7 +257,9 @@
         // Parse activation policy.
         //
 
-        m_activationPolicy = parseActivationPolicy(headerMap);
+        // This sets m_activationPolicy, m_includedPolicyClasses, and
+        // m_excludedPolicyClasses.
+        parseActivationPolicy(headerMap);
 
         // Do final checks and normalization of manifest.
         if (getManifestVersion().equals("2"))
@@ -311,6 +315,16 @@
         return m_activationPolicy;
     }
 
+    public String getActivationIncludeDirective()
+    {
+        return m_activationIncludeDir;
+    }
+
+    public String getActivationExcludeDirective()
+    {
+        return m_activationExcludeDir;
+    }
+
     public boolean isExtension()
     {
         return m_isExtension;
@@ -1188,9 +1202,9 @@
         return result;
     }
 
-    private static int parseActivationPolicy(Map headerMap)
+    private void parseActivationPolicy(Map headerMap)
     {
-        int policy = IModule.EAGER_ACTIVATION;
+        m_activationPolicy = IModule.EAGER_ACTIVATION;
 
         Object[][][] clauses = parseStandardHeader(
             (String) headerMap.get(Constants.BUNDLE_ACTIVATIONPOLICY));
@@ -1205,13 +1219,23 @@
             {
                 if (clauses[0][CLAUSE_PATHS_INDEX][i].equals(Constants.ACTIVATION_LAZY))
                 {
-                    policy = IModule.LAZY_ACTIVATION;
+                    m_activationPolicy = IModule.LAZY_ACTIVATION;
+                    for (int j = 0; j < clauses[0][CLAUSE_DIRECTIVES_INDEX].length; j++)
+                    {
+                        R4Directive dir = (R4Directive) clauses[0][CLAUSE_DIRECTIVES_INDEX][j];
+                        if (dir.getName().equalsIgnoreCase(Constants.INCLUDE_DIRECTIVE))
+                        {
+                            m_activationIncludeDir = dir.getValue();
+                        }
+                        else if (dir.getName().equalsIgnoreCase(Constants.EXCLUDE_DIRECTIVE))
+                        {
+                            m_activationExcludeDir = dir.getValue();
+                        }
+                    }
                     break;
                 }
             }
         }
-
-        return policy;
     }
 
     public static final int CLAUSE_PATHS_INDEX = 0;