More modifications for fragment support. Properly manages fragment
dependencies so that they are managed properly during the update/refresh
cycle. (FELIX-656)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@686513 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
index 223809a..74574f1 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
@@ -427,7 +427,12 @@
public String toString()
{
- return m_felix.getBundleSymbolicName(this) + " [" + getBundleId() +"]";
+ String sym = m_felix.getBundleSymbolicName(this);
+ if (sym != null)
+ {
+ return m_felix.getBundleSymbolicName(this) + " [" + getBundleId() +"]";
+ }
+ return "[" + getBundleId() +"]";
}
Object getSignerMatcher()
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 b446e48..dc40d8f 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -3225,7 +3225,6 @@
{
// Acquire locks for all impacted bundles.
FelixBundle[] bundles = acquireBundleRefreshLocks(targets);
-
boolean restart = false;
Bundle systemBundle = getBundle(0);
diff --git a/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java b/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java
index ff12f9d..dc08875 100644
--- a/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java
@@ -41,7 +41,7 @@
private final Logger m_logger;
private final IContent m_content;
private IContent[] m_contentPath;
- private IContent[] m_fragments = null;
+ private IContent[] m_fragmentContents = null;
private ISearchPolicy m_searchPolicy = null;
private IURLPolicy m_urlPolicy = null;
private ContentClassLoader m_classLoader;
@@ -66,6 +66,10 @@
{
m_contentPath[i].close();
}
+ for (int i = 0; (m_fragmentContents != null) && (i < m_fragmentContents.length); i++)
+ {
+ m_fragmentContents[i].close();
+ }
}
public IContent getContent()
@@ -89,23 +93,27 @@
return m_contentPath;
}
- public synchronized void setFragmentContents(IContent[] contents) throws Exception
+ public synchronized void attachFragmentContents(IContent[] fragmentContents)
+ throws Exception
{
- m_fragments = contents;
-// TODO: FRAGMENT - If this is not null, then we probably need to close
-// the existing contents; this might happen when a resource is loaded
-// from a bundle that could not be resolved.
-if (m_contentPath != null)
-{
-m_logger.log(Logger.LOG_DEBUG, "(FRAGMENT) CONTENT PATH SHOULD BE NULL = " + m_contentPath);
-}
+ // Close existing fragment contents.
+ if (m_fragmentContents != null)
+ {
+ for (int i = 0; i < m_fragmentContents.length; i++)
+ {
+ m_fragmentContents[i].close();
+ }
+ }
+ m_fragmentContents = fragmentContents;
+
+ if (m_contentPath != null)
+ {
+ for (int i = 0; i < m_contentPath.length; i++)
+ {
+ m_contentPath[i].close();
+ }
+ }
m_contentPath = initializeContentPath();
-String msg = "(FRAGMENT) HOST CLASSPATH = ";
-for (int i = 0; i < m_contentPath.length; i++)
-{
- msg += (m_contentPath[i].toString() + " ");
-}
-m_logger.log(Logger.LOG_DEBUG, msg);
}
public synchronized void setSearchPolicy(ISearchPolicy searchPolicy)
@@ -301,9 +309,9 @@
{
List contentList = new ArrayList();
calculateContentPath(m_content, contentList, true);
- for (int i = 0; (m_fragments != null) && (i < m_fragments.length); i++)
+ for (int i = 0; (m_fragmentContents != null) && (i < m_fragmentContents.length); i++)
{
- calculateContentPath(m_fragments[i], contentList, false);
+ calculateContentPath(m_fragmentContents[i], contentList, false);
}
return (IContent[]) contentList.toArray(new IContent[contentList.size()]);
}
@@ -365,10 +373,10 @@
// so try to search the fragments if necessary.
for (int fragIdx = 0;
searchFragments && (embeddedContent == null)
- && (m_fragments != null) && (fragIdx < m_fragments.length);
+ && (m_fragmentContents != null) && (fragIdx < m_fragmentContents.length);
fragIdx++)
{
- embeddedContent = m_fragments[fragIdx].getEntryAsContent(classPathStrings[i]);
+ embeddedContent = m_fragmentContents[fragIdx].getEntryAsContent(classPathStrings[i]);
}
// If we found the embedded content, then add it to the
// class path content list.
diff --git a/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4SearchPolicyCore.java b/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4SearchPolicyCore.java
index 9fddfa1..e4786fe 100755
--- a/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4SearchPolicyCore.java
+++ b/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4SearchPolicyCore.java
@@ -1034,12 +1034,6 @@
targetFragment = rootModule;
List hostList = getPotentialHosts(targetFragment);
rootModule = (IModule) hostList.get(0);
-String msg = "(FRAGMENT) POSSILE HOST(S): ";
-for (int i = 0; i < hostList.size(); i++)
-{
- msg += (hostList.get(i).toString() + " ");
-}
-m_logger.log(Logger.LOG_DEBUG, msg);
}
// Get the available fragments for the host.
@@ -1060,7 +1054,7 @@
String symName = (String) entry.getKey();
IModule[] fragments = (IModule[]) entry.getValue();
m_logger.log(Logger.LOG_DEBUG, "(FRAGMENT) WIRE: "
- + rootModule + " -> " + symName + "[" + fragments.length + "] -> " + fragments[0]);
+ + rootModule + " -> " + symName + " -> " + fragments[0]);
}
// This variable maps an unresolved module to a list of candidate
@@ -1113,14 +1107,13 @@
{
Map.Entry entry = (Map.Entry) iter.next();
IModule[] fragments = (IModule[]) entry.getValue();
- list.add(fragments[0].getContentLoader().getContent()
- .getEntryAsContent(FelixConstants.CLASS_PATH_DOT));
+// TODO: FRAGMENT - For now, just attach first candidate.
+ list.add(fragments[0]);
}
try
{
- ((ContentLoaderImpl) rootModule.getContentLoader())
- .setFragmentContents(
- (IContent[]) list.toArray(new IContent[list.size()]));
+ ((ModuleImpl) rootModule).attachFragments(
+ (IModule[]) list.toArray(new IModule[list.size()]));
}
catch (Exception ex)
{
@@ -2944,6 +2937,16 @@
}
}
+ // Set fragments to null, which will remove the module from all
+ // of its dependent fragment modules.
+ try
+ {
+ ((ModuleImpl) event.getModule()).attachFragments(null);
+ }
+ catch (Exception ex)
+ {
+ m_logger.log(Logger.LOG_ERROR, "Error detaching fragments.", ex);
+ }
// Set wires to null, which will remove the module from all
// of its dependent modules.
((ModuleImpl) event.getModule()).setWires(null);
diff --git a/framework/src/main/java/org/apache/felix/moduleloader/ModuleImpl.java b/framework/src/main/java/org/apache/felix/moduleloader/ModuleImpl.java
index 32d50cb..43757a2 100644
--- a/framework/src/main/java/org/apache/felix/moduleloader/ModuleImpl.java
+++ b/framework/src/main/java/org/apache/felix/moduleloader/ModuleImpl.java
@@ -22,6 +22,8 @@
import java.util.Enumeration;
import org.apache.felix.framework.Logger;
+import org.apache.felix.framework.searchpolicy.ContentLoaderImpl;
+import org.apache.felix.framework.util.FelixConstants;
public class ModuleImpl implements IModule
{
@@ -30,6 +32,7 @@
private boolean m_removalPending = false;
private IModuleDefinition m_md = null;
private IContentLoader m_contentLoader = null;
+ private IModule[] m_fragments = null;
private IWire[] m_wires = null;
private IModule[] m_dependents = new IModule[0];
@@ -60,6 +63,36 @@
m_contentLoader = contentLoader;
}
+ public synchronized void attachFragments(IModule[] fragments) throws Exception
+ {
+ // Remove module from old fragment dependencies.
+ // We will generally only remove module fragment
+ // dependencies when we are uninstalling the module.
+ for (int i = 0; (m_fragments != null) && (i < m_fragments.length); i++)
+ {
+ ((ModuleImpl) m_fragments[i]).removeDependent(this);
+ }
+
+ // Update the dependencies on the new fragments.
+ m_fragments = fragments;
+ if (m_fragments != null)
+ {
+ // We need to add ourself as a dependent of each fragment
+ // module. We also need to create an array of fragment contents
+ // to attach to our content loader.
+ IContent[] fragmentContents = new IContent[m_fragments.length];
+ for (int i = 0; (m_fragments != null) && (i < m_fragments.length); i++)
+ {
+ ((ModuleImpl) m_fragments[i]).addDependent(this);
+ fragmentContents[i] =
+ m_fragments[i].getContentLoader().getContent()
+ .getEntryAsContent(FelixConstants.CLASS_PATH_DOT);
+ }
+ // Now attach the fragment contents to our content loader.
+ ((ContentLoaderImpl) m_contentLoader).attachFragmentContents(fragmentContents);
+ }
+ }
+
public synchronized IWire[] getWires()
{
return m_wires;
@@ -80,7 +113,7 @@
}
}
- public synchronized void addDependent(IModule module)
+ private synchronized void addDependent(IModule module)
{
// Make sure the dependent module is not already present.
for (int i = 0; i < m_dependents.length; i++)
@@ -96,7 +129,7 @@
m_dependents = tmp;
}
- public synchronized void removeDependent(IModule module)
+ private synchronized void removeDependent(IModule module)
{
// Make sure the dependent module is not already present.
for (int i = 0; i < m_dependents.length; i++)