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 2010/03/01 19:47:07 UTC
svn commit: r917641 -
/felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
Author: rickhall
Date: Mon Mar 1 18:47:06 2010
New Revision: 917641
URL: http://svn.apache.org/viewvc?rev=917641&view=rev
Log:
Reexport visibility support ported from resolver prototype.
Modified:
felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
Modified: felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java?rev=917641&r1=917640&r2=917641&view=diff
==============================================================================
--- felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java (original)
+++ felix/sandbox/rickhall/framework-proto/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java Mon Mar 1 18:47:06 2010
@@ -37,7 +37,6 @@
import org.apache.felix.framework.capabilityset.Module;
import org.apache.felix.framework.capabilityset.Requirement;
import org.apache.felix.framework.capabilityset.Wire;
-import org.apache.felix.framework.util.Util;
import org.apache.felix.framework.util.manifestparser.R4Library;
import org.apache.felix.framework.util.manifestparser.RequirementImpl;
import org.osgi.framework.Constants;
@@ -63,7 +62,6 @@
{
System.out.println("+++ PROTO3 RESOLVER");
m_logger = logger;
-// TODO: FELIX3 - Need to implement execution environment checking.
m_fwkExecEnvStr = (fwkExecEnvStr != null) ? fwkExecEnvStr.trim() : null;
m_fwkExecEnvSet = parseExecutionEnvironments(fwkExecEnvStr);
@@ -84,6 +82,8 @@
m_invokeCounts.put(methodName, count);
}
+ Map<Module, List<Wire>> wireMap = new HashMap<Module, List<Wire>>();
+
Map<Module, Packages> modulePkgMap = new HashMap<Module, Packages>();
if (!module.isResolved())
@@ -129,10 +129,11 @@
throw rethrow;
}
//dumpModulePkgMap(modulePkgMap);
- }
- Map<Module, List<Wire>> wireMap =
- populateWireMap(module, modulePkgMap, new HashMap<Module, List<Wire>>());
+ wireMap =
+ populateWireMap(module, modulePkgMap, wireMap,
+ candidateMap);
+ }
if (m_isInvokeCount)
{
@@ -161,6 +162,8 @@
{
m_candidatePermutations.clear();
+ Map<Module, List<Wire>> wireMap = new HashMap<Module, List<Wire>>();
+
Map<Module, Packages> modulePkgMap = new HashMap<Module, Packages>();
//System.out.println("+++ DYNAMICALLY RESOLVING " + module + " - " + pkgName);
@@ -197,9 +200,9 @@
throw rethrow;
}
//dumpModulePkgMap(modulePkgMap);
- Map<Module, List<Wire>> wireMap =
+ wireMap =
populateDynamicWireMap(
- module, pkgName, modulePkgMap, new HashMap<Module, List<Wire>>());
+ module, pkgName, modulePkgMap, wireMap, candidateMap);
//System.out.println("+++ DYNAMIC SUCCESS: " + wireMap.get(module));
return wireMap;
@@ -691,6 +694,12 @@
{
System.out.println("RE: " + ex);
ex.printStackTrace();
+
+// TODO: FELIX3 RESOLVER - Is it ok to remove the failed candidate? By removing
+// it we keep the candidateMap up to date with the selected candidate, but
+// theoretically this eliminates some potential combinations. Are those
+// combinations guaranteed to be failures so eliminating them is ok?
+ it.remove();
if (!it.hasNext() && !req.isOptional())
{
throw new ResolveException("Unresolved constraint "
@@ -776,6 +785,11 @@
{
System.out.println("RE: " + ex);
ex.printStackTrace();
+// TODO: FELIX3 RESOLVER - Is it ok to remove the failed candidate? By removing
+// it we keep the candidateMap up to date with the selected candidate, but
+// theoretically this eliminates some potential combinations. Are those
+// combinations guaranteed to be failures so eliminating them is ok?
+ it.remove();
if (!it.hasNext() && !req.isOptional())
{
throw new ResolveException("Unresolved constraint "
@@ -882,8 +896,21 @@
List<Blame> blames = entry.getValue();
for (Blame blame : blames)
{
- if (blame.m_reqs.get(blame.m_reqs.size() - 1)
- .getDirective(Constants.VISIBILITY_DIRECTIVE) != null)
+// TODO: FELIX3 RESOLVER - Since a single module requirement can include many packages,
+// it is likely we call merge too many times for the same module req. If we knew
+// which candidates were being used to resolve this candidate's module dependencies,
+// then we could just try to merge them directly. This info would also help in
+// in creating wires, since we ultimately want to create wires for the selected
+// candidates, which we are trying to deduce from the package space, but if we
+// knew the selected candidates, we'd be done.
+ if (blame.m_cap.getModule().equals(current))
+ {
+ continue;
+ }
+
+ Directive dir = blame.m_reqs.get(blame.m_reqs.size() - 1)
+ .getDirective(Constants.VISIBILITY_DIRECTIVE);
+ if ((dir != null) && dir.getValue().equals(Constants.VISIBILITY_REEXPORT))
{
mergeCandidatePackage(
current,
@@ -984,7 +1011,7 @@
currentRequiredBlames = new ArrayList<Blame>();
currentPkgsCopy.m_requiredPkgs.put(pkgName, currentRequiredBlames);
}
-// TODO: PROTO2 RESOLVER - This is potentially modifying the original, we need to modify a copy.
+// TODO: PROTO3 RESOLVER - This is potentially modifying the original, we need to modify a copy.
currentRequiredBlames.add(candBlame);
}
else
@@ -1269,7 +1296,7 @@
private static Map<Module, List<Wire>> populateWireMap(
Module module, Map<Module, Packages> modulePkgMap,
- Map<Module, List<Wire>> wireMap)
+ Map<Module, List<Wire>> wireMap, Map<Requirement, Set<Capability>> candidateMap)
{
if (m_isInvokeCount)
{
@@ -1286,87 +1313,36 @@
List<Wire> packageWires = new ArrayList<Wire>();
List<Wire> moduleWires = new ArrayList<Wire>();
- Packages pkgs = modulePkgMap.get(module);
- for (Entry<String, Blame> entry : pkgs.m_importedPkgs.entrySet())
- {
- if (!entry.getValue().m_cap.getModule().isResolved())
- {
- populateWireMap(entry.getValue().m_cap.getModule(), modulePkgMap, wireMap);
- }
-
- // Ignore modules that import themselves.
- if (!module.equals(entry.getValue().m_cap.getModule()))
- {
- packageWires.add(
- new WireImpl(module,
- entry.getValue().m_reqs.get(entry.getValue().m_reqs.size() - 1),
- entry.getValue().m_cap.getModule(),
- entry.getValue().m_cap));
- }
- }
- List<Requirement> rbReqs = new ArrayList<Requirement>();
for (Requirement req : module.getRequirements())
{
- if (req.getNamespace().equals(Capability.MODULE_NAMESPACE))
+ Set<Capability> cands = candidateMap.get(req);
+ if ((cands != null) && (cands.size() > 0))
{
- rbReqs.add(req);
- }
- }
- if (!rbReqs.isEmpty())
- {
- Map<Requirement, Capability> rbMap =
- new HashMap<Requirement, Capability>();
-// TODO: FELIX3 - This approach isn't very efficient since it keeps recalculating the
-// module wire for each package exported by the candidate module.
- for (Entry<String, List<Blame>> entry : pkgs.m_requiredPkgs.entrySet())
- {
- for (Blame blame : entry.getValue())
+ Capability cand = cands.iterator().next();
+ if (!cand.getModule().isResolved())
{
- // Ignore packages required from self, which can
- // happen in cycles.
- if (!blame.m_cap.getModule().equals(module))
- {
- for (Requirement rbReq : rbReqs)
- {
- if (blame.m_reqs.get(blame.m_reqs.size() - 1).equals(rbReq))
- {
- List<Capability> moduleCaps =
- Util.getCapabilityByNamespace(
- blame.m_cap.getModule(), Capability.MODULE_NAMESPACE);
- Capability cap = rbMap.get(rbReq);
- if (cap == null)
- {
- rbMap.put(rbReq, moduleCaps.get(0));
- }
- if (!blame.m_cap.getModule().isResolved())
- {
- populateWireMap(
- blame.m_cap.getModule(), modulePkgMap, wireMap);
- }
- break;
- }
- }
- }
+ populateWireMap(cand.getModule(),
+ modulePkgMap, wireMap, candidateMap);
}
- }
-
- // Loop through RB requirements to keep the wires in the
- // correct order, which is required by the spec.
- for (Requirement rbReq : rbReqs)
- {
- Capability cap = rbMap.get(rbReq);
- if (cap != null)
+ // Ignore modules that import themselves.
+ if (req.getNamespace().equals(Capability.PACKAGE_NAMESPACE)
+ && !module.equals(cand.getModule()))
{
- // Ignore modules that import themselves.
- if (!module.equals(cap.getModule()))
- {
- moduleWires.add(
- new WireModuleImpl(module,
- rbReq,
- cap.getModule(),
- cap,
- pkgs.getRequiredPackages(cap.getModule())));
- }
+ packageWires.add(
+ new WireImpl(module,
+ req,
+ cand.getModule(),
+ cand));
+ }
+ else if (req.getNamespace().equals(Capability.MODULE_NAMESPACE))
+ {
+ Packages candPkgs = modulePkgMap.get(cand.getModule());
+ moduleWires.add(
+ new WireModuleImpl(module,
+ req,
+ cand.getModule(),
+ cand,
+ candPkgs.getExportedAndReexportedPackages()));
}
}
}
@@ -1381,7 +1357,7 @@
private static Map<Module, List<Wire>> populateDynamicWireMap(
Module module, String pkgName, Map<Module, Packages> modulePkgMap,
- Map<Module, List<Wire>> wireMap)
+ Map<Module, List<Wire>> wireMap, Map<Requirement, Set<Capability>> candidateMap)
{
if (m_isInvokeCount)
{
@@ -1400,7 +1376,8 @@
{
if (!entry.getValue().m_cap.getModule().isResolved())
{
- populateWireMap(entry.getValue().m_cap.getModule(), modulePkgMap, wireMap);
+ populateWireMap(entry.getValue().m_cap.getModule(), modulePkgMap, wireMap,
+ candidateMap);
}
// Ignore modules that import themselves.
@@ -1551,14 +1528,22 @@
m_usedPkgs.putAll(packages.m_usedPkgs);
}
- public List<String> getRequiredPackages(Module source)
+ public List<String> getExportedAndReexportedPackages()
{
List<String> pkgs = new ArrayList();
+ for (Entry<String, Blame> entry : m_exportedPkgs.entrySet())
+ {
+ pkgs.add((String)
+ entry.getValue().m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue());
+ }
for (Entry<String, List<Blame>> entry : m_requiredPkgs.entrySet())
{
for (Blame blame : entry.getValue())
{
- if (blame.m_cap.getModule().equals(source))
+ Directive dir = blame.m_reqs.get(
+ blame.m_reqs.size() - 1).getDirective(Constants.VISIBILITY_DIRECTIVE);
+ if ((dir != null)
+ && dir.getValue().equals(Constants.VISIBILITY_REEXPORT))
{
pkgs.add((String)
blame.m_cap.getAttribute(Capability.PACKAGE_ATTR).getValue());