felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rickh...@apache.org
Subject svn commit: r906626 - in /felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework: Felix.java FelixResolverState.java ModuleImpl.java
Date Thu, 04 Feb 2010 19:56:02 GMT
Author: rickhall
Date: Thu Feb  4 19:56:02 2010
New Revision: 906626

URL: http://svn.apache.org/viewvc?rev=906626&view=rev
Log:
Initial support for fragment conflict detection.

Modified:
    felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/Felix.java
    felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/FelixResolverState.java
    felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/ModuleImpl.java

Modified: felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/Felix.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/Felix.java?rev=906626&r1=906625&r2=906626&view=diff
==============================================================================
--- felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/Felix.java
(original)
+++ felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/Felix.java
Thu Feb  4 19:56:02 2010
@@ -24,6 +24,7 @@
 import java.security.*;
 import java.util.*;
 import java.util.Map.Entry;
+import org.apache.felix.framework.ModuleImpl.FragmentRequirement;
 import org.apache.felix.framework.ServiceRegistry.ServiceRegistryCallbacks;
 import org.apache.felix.framework.cache.BundleArchive;
 import org.apache.felix.framework.cache.BundleCache;
@@ -3893,12 +3894,38 @@
                         // Check singleton status.
                         m_resolverState.checkSingleton(newRootModule);
 
-                        // Resolve the module.
-                        Map<Module, List<Wire>> wireMap =
-                            m_resolver.resolve(m_resolverState, newRootModule);
+                        boolean repeat;
+                        do
+                        {
+                            repeat = false;
+                            try
+                            {
+                                // Resolve the module.
+                                Map<Module, List<Wire>> wireMap =
+                                    m_resolver.resolve(m_resolverState, newRootModule);
 
-                        // Mark all modules as resolved.
-                        markResolvedModules(wireMap);
+                                // Mark all modules as resolved.
+                                markResolvedModules(wireMap);
+                            }
+                            catch (ResolveException ex)
+                            {
+                                if ((ex.getRequirement() != null)
+                                    && (ex.getRequirement() instanceof FragmentRequirement)
+                                    && (rootModule !=
+                                        ((FragmentRequirement) ex.getRequirement()).getFragment()))
+                                {
+                                    m_resolverState.detachFragment(
+                                        newRootModule,
+                                        ((FragmentRequirement) ex.getRequirement()).getFragment());
+                                    repeat = true;
+                                }
+                                else
+                                {
+                                    throw ex;
+                                }
+                            }
+                        }
+                        while (repeat);
                     }
                 }
                 finally

Modified: felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/FelixResolverState.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/FelixResolverState.java?rev=906626&r1=906625&r2=906626&view=diff
==============================================================================
--- felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/FelixResolverState.java
(original)
+++ felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/FelixResolverState.java
Thu Feb  4 19:56:02 2010
@@ -147,6 +147,29 @@
         }
     }
 
+    public void detachFragment(Module host, Module fragment)
+    {
+        List<Module> fragments = ((ModuleImpl) host).getFragments();
+        fragments.remove(fragment);
+        try
+        {
+            ((ModuleImpl) host).attachFragments(fragments);
+        }
+        catch (Exception ex)
+        {
+            // Try to clean up by removing all fragments.
+            try
+            {
+                ((ModuleImpl) host).attachFragments(null);
+            }
+            catch (Exception ex2)
+            {
+            }
+            m_logger.log(Logger.LOG_ERROR,
+                "Serious error attaching fragments.", ex);
+        }
+    }
+
     public void checkSingleton(Module module)
     {
         // Check if this module is a singleton.
@@ -255,9 +278,6 @@
                     }
                 }
 
-                // Check if fragment conflicts with existing metadata.
-                checkForConflicts(host, fragmentList);
-
                 // Attach the fragments to the host.
                 fragments = (fragmentList.size() == 0) ? null : fragmentList;
                 try
@@ -339,9 +359,6 @@
                         }
                     }
 
-                    // Check if fragment conflicts with existing metadata.
-                    checkForConflicts(host, fragmentList);
-
                     // Attach the fragments to the host.
                     try
                     {
@@ -432,203 +449,6 @@
         return matchingHosts;
     }
 
-    private void checkForConflicts(Module host, List fragmentList)
-    {
-        if ((fragmentList == null) || (fragmentList.size() == 0))
-        {
-            return;
-        }
-// TODO: FELIX3 - Fix fragment conflict detection.
-/*
-        // Verify the fragments do not have conflicting imports.
-        // For now, just check for duplicate imports, but in the
-        // future we might want to make this more fine grained.
-        // First get the host's imported packages.
-        final int MODULE_IDX = 0, REQ_IDX = 1;
-        Map ipMerged = new HashMap();
-        Map rbMerged = new HashMap();
-        List<Requirement> reqs = host.getRequirements();
-        for (int reqIdx = 0; (reqs != null) && (reqIdx < reqs.size()); reqIdx++)
-        {
-            if (reqs.get(reqIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE))
-            {
-                ipMerged.put(
-                    ((Requirement) reqs[reqIdx]).getTargetName(),
-                    new Object[] { host, reqs[reqIdx] });
-            }
-            else if (reqs[reqIdx].getNamespace().equals(ICapability.MODULE_NAMESPACE))
-            {
-                rbMerged.put(
-                    ((Requirement) reqs[reqIdx]).getTargetName(),
-                    new Object[] { host, reqs[reqIdx] });
-            }
-        }
-        // Loop through each fragment verifying it does no conflict,
-        // adding its package and bundle dependencies if they do not
-        // conflict and removing the fragment if it does conflict.
-        for (Iterator it = fragmentList.iterator(); it.hasNext(); )
-        {
-            IModule fragment = (IModule) it.next();
-            reqs = fragment.getRequirements();
-            Map ipFragment = new HashMap();
-            Map rbFragment = new HashMap();
-            for (int reqIdx = 0;
-                (reqs != null) && (reqIdx < reqs.length);
-                reqIdx++)
-            {
-                if (reqs[reqIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE)
-                    || reqs[reqIdx].getNamespace().equals(ICapability.MODULE_NAMESPACE))
-                {
-                    String targetName = ((Requirement) reqs[reqIdx]).getTargetName();
-                    Map mergedReqMap =
-                        (reqs[reqIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
-                            ? ipMerged : rbMerged;
-                    Map fragmentReqMap =
-                        (reqs[reqIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
-                            ? ipFragment : rbFragment;
-                    Object[] existing = (Object[]) mergedReqMap.get(targetName);
-                    if (existing == null)
-                    {
-                        fragmentReqMap.put(targetName, new Object[] { fragment, reqs[reqIdx]
});
-                    }
-                    else if (isRequirementConflicting(
-                        (Requirement) existing[REQ_IDX], (Requirement) reqs[reqIdx]))
-                    {
-                        ipFragment.clear();
-                        rbFragment.clear();
-                        it.remove();
-                        m_logger.log(
-                            Logger.LOG_DEBUG,
-                            "Excluding fragment " + fragment.getSymbolicName()
-                            + " from " + host.getSymbolicName()
-                            + " due to conflict with "
-                            + (reqs[reqIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE)
-                                ? "imported package " : "required bundle ")
-                            + targetName + " from "
-                            + ((IModule) existing[MODULE_IDX]).getSymbolicName());
-                        // No need to finish processing current fragment.
-                        break;
-                    }
-                }
-            }
-
-            // Merge non-conflicting requirements into overall set
-            // of requirements and continue checking for conflicts
-            // with the next fragment.
-            for (Iterator it2 = ipFragment.entrySet().iterator(); it2.hasNext(); )
-            {
-                Map.Entry entry = (Map.Entry) it2.next();
-                ipMerged.put(entry.getKey(), entry.getValue());
-            }
-            for (Iterator it2 = rbFragment.entrySet().iterator(); it2.hasNext(); )
-            {
-                Map.Entry entry = (Map.Entry) it2.next();
-                rbMerged.put(entry.getKey(), entry.getValue());
-            }
-        }
-*/
-    }
-/*
-    private boolean isRequirementConflicting(
-        Requirement existing, Requirement additional)
-    {
-        // If the namespace is not the same, then they do NOT conflict.
-        if (!existing.getNamespace().equals(additional.getNamespace()))
-        {
-            return false;
-        }
-        // If the target name is not the same, then they do NOT conflict.
-        if (!existing.getTargetName().equals(additional.getTargetName()))
-        {
-            return false;
-        }
-        // If the target version range is not the same, then they conflict.
-        if (!existing.getTargetVersionRange().equals(additional.getTargetVersionRange()))
-        {
-            return true;
-        }
-        // If optionality is not the same, then they conflict, unless
-        // the existing requirement is not optional, then it doesn't matter
-        // what subsequent requirements are since non-optional is stronger
-        // than optional.
-        if (existing.isOptional() && (existing.isOptional() != additional.isOptional()))
-        {
-            return true;
-        }
-        // Verify directives are the same.
-        // This is sort of ugly, but we need to remove
-        // the resolution directive, since it is effectively
-        // test above when checking optionality.
-        // Put directives in a map, since ordering is arbitrary.
-        final R4Directive[] exDirs = (existing.getDirectives() == null)
-            ? new R4Directive[0] : existing.getDirectives();
-        final Map exDirMap = new HashMap();
-        for (int i = 0; i < exDirs.length; i++)
-        {
-            if (!exDirs[i].getName().equals(Constants.RESOLUTION_DIRECTIVE))
-            {
-                exDirMap.put(exDirs[i].getName(), exDirs[i]);
-            }
-        }
-        final R4Directive[] addDirs = (additional.getDirectives() == null)
-            ? new R4Directive[0] : additional.getDirectives();
-        final Map addDirMap = new HashMap();
-        for (int i = 0; i < addDirs.length; i++)
-        {
-            if (!addDirs[i].getName().equals(Constants.RESOLUTION_DIRECTIVE))
-            {
-                addDirMap.put(addDirs[i].getName(), addDirs[i]);
-            }
-        }
-        // If different number of directives, then they conflict.
-        if (exDirMap.size() != addDirMap.size())
-        {
-            return true;
-        }
-        // If directive values do not match, then they conflict.
-        for (Iterator it = addDirMap.entrySet().iterator(); it.hasNext(); )
-        {
-            final Map.Entry entry = (Map.Entry) it.next();
-            final String name = (String) entry.getKey();
-            final R4Directive addDir = (R4Directive) entry.getValue();
-            final R4Directive exDir = (R4Directive) exDirMap.get(name);
-            if ((exDir == null) ||
-                !exDir.getValue().equals(addDir.getValue()))
-            {
-                return true;
-            }
-        }
-        // Verify attributes are the same.
-        final R4Attribute[] exAttrs = (existing.getAttributes() == null)
-            ? new R4Attribute[0] : existing.getAttributes();
-        final R4Attribute[] addAttrs = (additional.getAttributes() == null)
-            ? new R4Attribute[0] : additional.getAttributes();
-        // If different number of attributes, then they conflict.
-        if (exAttrs.length != addAttrs.length)
-        {
-            return true;
-        }
-        // Put attributes in a map, since ordering is arbitrary.
-        final Map exAttrMap = new HashMap();
-        for (int i = 0; i < exAttrs.length; i++)
-        {
-            exAttrMap.put(exAttrs[i].getName(), exAttrs[i]);
-        }
-        // If attribute values do not match, then they conflict.
-        for (int i = 0; i < addAttrs.length; i++)
-        {
-            final R4Attribute exAttr = (R4Attribute) exAttrMap.get(addAttrs[i].getName());
-            if ((exAttr == null) ||
-                !exAttr.getValue().equals(addAttrs[i].getValue()) ||
-                (exAttr.isMandatory() != addAttrs[i].isMandatory()))
-            {
-                return true;
-            }
-        }
-        // They do no conflict.
-        return false;
-    }
-*/
     private void addHost(Module host)
     {
         // When a module is added, we first need to pre-merge any potential fragments
@@ -645,9 +465,6 @@
         // Attach any fragments we found for this host.
         if (fragments.size() > 0)
         {
-            // Check if fragment conflicts with existing metadata.
-            checkForConflicts(host, fragments);
-
             // Attach the fragments to the host.
             try
             {

Modified: felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/ModuleImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/ModuleImpl.java?rev=906626&r1=906625&r2=906626&view=diff
==============================================================================
--- felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/ModuleImpl.java
(original)
+++ felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/ModuleImpl.java
Thu Feb  4 19:56:02 2010
@@ -18,6 +18,7 @@
  */
 package org.apache.felix.framework;
 
+import org.apache.felix.framework.capabilityset.SimpleFilter;
 import org.apache.felix.moduleloader.*;
 import java.io.IOException;
 import java.io.InputStream;
@@ -309,7 +310,9 @@
                     if (reqs.get(reqIdx).getNamespace().equals(Capability.PACKAGE_NAMESPACE)
                         || reqs.get(reqIdx).getNamespace().equals(Capability.MODULE_NAMESPACE))
                     {
-                        reqList.add(reqs.get(reqIdx));
+                        reqList.add(
+                            new FragmentRequirement(
+                                reqs.get(reqIdx), m_fragments.get(fragIdx)));
                     }
                 }
             }
@@ -2215,4 +2218,46 @@
 
         return sb.toString();
     }
+
+    static class FragmentRequirement implements Requirement
+    {
+        private final Requirement m_req;
+        private final Module m_fragment;
+
+        public FragmentRequirement(Requirement req, Module fragment)
+        {
+            m_req = req;
+            m_fragment = fragment;
+        }
+
+        public Module getFragment()
+        {
+            return m_fragment;
+        }
+
+        public String getNamespace()
+        {
+            return m_req.getNamespace();
+        }
+
+        public SimpleFilter getFilter()
+        {
+            return m_req.getFilter();
+        }
+
+        public boolean isOptional()
+        {
+            return m_req.isOptional();
+        }
+
+        public Directive getDirective(String name)
+        {
+            return m_req.getDirective(name);
+        }
+
+        public List<Directive> getDirectives()
+        {
+            return m_req.getDirectives();
+        }
+    }
 }
\ No newline at end of file



Mime
View raw message