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/12/24 15:58:30 UTC
svn commit: r893769 -
/felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/proto2/Proto2Resolver.java
Author: rickhall
Date: Thu Dec 24 14:58:30 2009
New Revision: 893769
URL: http://svn.apache.org/viewvc?rev=893769&view=rev
Log:
Focus on module package space.
Modified:
felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/proto2/Proto2Resolver.java
Modified: felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/proto2/Proto2Resolver.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/proto2/Proto2Resolver.java?rev=893769&r1=893768&r2=893769&view=diff
==============================================================================
--- felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/proto2/Proto2Resolver.java (original)
+++ felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/proto2/Proto2Resolver.java Thu Dec 24 14:58:30 2009
@@ -118,22 +118,22 @@
{
System.out.println(module);
System.out.println(" EXPORTED");
- for (Entry<String, Constraint> entry : packages.m_exportedPkgs.entrySet())
+ for (Entry<String, Capability> entry : packages.m_exportedPkgs.entrySet())
{
System.out.println(" " + entry.getKey() + " - " + entry.getValue());
}
System.out.println(" IMPORTED");
- for (Entry<String, Constraint> entry : packages.m_importedPkgs.entrySet())
+ for (Entry<String, Capability> entry : packages.m_importedPkgs.entrySet())
{
System.out.println(" " + entry.getKey() + " - " + entry.getValue());
}
System.out.println(" REQUIRED");
- for (Entry<String, Constraint> entry : packages.m_requiredPkgs.entrySet())
+ for (Entry<String, List<Capability>> entry : packages.m_requiredPkgs.entrySet())
{
System.out.println(" " + entry.getKey() + " - " + entry.getValue());
}
System.out.println(" USED");
- for (Entry<String, List<Constraint>> entry : packages.m_usedPkgs.entrySet())
+ for (Entry<String, List<Capability>> entry : packages.m_usedPkgs.entrySet())
{
System.out.println(" " + entry.getKey() + " - " + entry.getValue());
}
@@ -220,47 +220,105 @@
if (candCap.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
{
+ mergeCandidatePackage(current, false, candCap, modulePkgMap);
+ }
+ else if (candCap.getNamespace().equals(Capability.MODULE_NAMESPACE))
+ {
+ // Get the candidate's package space to determine which packages
+ // will be visible to the current module.
+ Packages candPkgs = modulePkgMap.get(candCap.getModule());
+
+// TODO: PROTO2 RESOLVER - For now assume only exports, but eventually we also
+// have to support re-exported packages.
+ for (Entry<String, Capability> entry : candPkgs.m_exportedPkgs.entrySet())
+ {
+ mergeCandidatePackage(current, true, entry.getValue(), modulePkgMap);
+ }
+ }
+ }
+
+ private void mergeCandidatePackage(
+ Module current, boolean requires,
+ Capability candCap, Map<Module, Packages> modulePkgMap)
+ {
+ if (m_isInvokeCount)
+ {
+ String methodName = new Exception().fillInStackTrace().getStackTrace()[0].getMethodName();
+ Long count = m_invokeCounts.get(methodName);
+ count = (count == null) ? new Long(1) : new Long(count.longValue() + 1);
+ m_invokeCounts.put(methodName, count);
+ }
+
+ if (candCap.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+ {
System.out.println("+++ MERGING " + candCap + " INTO " + current);
String pkgName = (String)
candCap.getAttribute(Capability.PACKAGE_ATTR).getValue();
-
Packages candPkgs = modulePkgMap.get(candCap.getModule());
- Constraint candConstraint = candPkgs.m_exportedPkgs.get(pkgName);
+
+ // Since this capability represents a package, it will become
+ // a hard constraint on the module's package space, so we need
+ // to make sure it doesn't conflict with any other hard constraints
+ // or any other uses constraints.
+
+ //
+ // First, check to see if the capability conflicts with
+ // any existing hard constraints.
+ //
Packages currentPkgs = modulePkgMap.get(current);
- Constraint currentExportedConstraint = currentPkgs.m_exportedPkgs.get(pkgName);
- Constraint currentImportedConstraint = currentPkgs.m_importedPkgs.get(pkgName);
- Constraint currentRequiredConstraint = currentPkgs.m_requiredPkgs.get(pkgName);
-
- if (((currentExportedConstraint != null)
- && !currentExportedConstraint.m_sources.containsAll(candConstraint.m_sources))
- || ((currentImportedConstraint != null)
- && !currentImportedConstraint.m_sources.containsAll(candConstraint.m_sources))
- || ((currentRequiredConstraint != null)
- && !currentRequiredConstraint.m_sources.containsAll(candConstraint.m_sources)))
+ Capability currentExportedCap = currentPkgs.m_exportedPkgs.get(pkgName);
+ Capability currentImportedCap = currentPkgs.m_importedPkgs.get(pkgName);
+ List<Capability> currentRequiredCaps = currentPkgs.m_requiredPkgs.get(pkgName);
+
+ if (!requires &&
+ (((currentExportedCap != null) && !currentExportedCap.equals(candCap))
+ || ((currentImportedCap != null) && !currentImportedCap.equals(candCap))
+ || ((currentRequiredCaps != null) && !currentRequiredCaps.contains(candCap))))
{
+dumpModulePkgs(current, currentPkgs);
throw new ResolveException("Constraint violation between "
+ current + " and " + candCap.getModule()
+ " for " + pkgName);
}
- List<Constraint> currentUsedSources = currentPkgs.m_usedPkgs.get(pkgName);
- checkExistingUsesConstraints(current, pkgName, currentUsedSources, candConstraint);
+ //
+ // Second, check to see if the capability conflicts with
+ // any existing uses constraints
+ //
+
+ List<Capability> currentUsedCapabilities = currentPkgs.m_usedPkgs.get(pkgName);
+ checkExistingUsesConstraints(current, pkgName, currentUsedCapabilities, candCap);
+
+ //
+ // Last, check to see if any uses constraints implied by the
+ // candidate conflict with any of the existing hard constraints.
+ //
+ // For now, create a copy of the module's package space and
+ // add the current candidate to the imported packages.
Packages currentPkgsCopy = new Packages(currentPkgs);
- // Add the candidate package to the current set of packages.
- currentPkgsCopy.m_importedPkgs.put(pkgName, candConstraint);
-
- // Verify the candidate's uses constraints do not conflict.
- for (Capability cap : candConstraint.m_sources)
+ if (requires)
{
- for (String usedPkg : cap.getUses())
+ if (currentRequiredCaps == null)
{
- verifyUses(current, currentPkgsCopy, candCap, modulePkgMap, usedPkg);
+ currentRequiredCaps = new ArrayList<Capability>();
+ currentPkgsCopy.m_requiredPkgs.put(pkgName, currentRequiredCaps);
}
+// TODO: PROTO2 RESOLVER - This is potentially modifying the original, we need to modify a copy.
+ currentRequiredCaps.add(candCap);
+ }
+ else
+ {
+ currentPkgsCopy.m_importedPkgs.put(pkgName, candCap);
}
+ // Verify and merge the candidate's transitive uses constraints.
+ verifyAndMergeUses(current, currentPkgsCopy, candCap, modulePkgMap);
+
+ // If we are here, then there were no conflict, so we should update
+ // the module's package space.
currentPkgs.m_exportedPkgs.putAll(currentPkgsCopy.m_exportedPkgs);
currentPkgs.m_importedPkgs.putAll(currentPkgsCopy.m_importedPkgs);
currentPkgs.m_requiredPkgs.putAll(currentPkgsCopy.m_requiredPkgs);
@@ -270,30 +328,29 @@
}
private void checkExistingUsesConstraints(
- Module current, String pkgName, List<Constraint> existingConstraints,
- Constraint candConstraint)
+ Module current, String pkgName, List<Capability> currentUsedCapabilities,
+ Capability candCap)
{
- for (int i = 0; (existingConstraints != null) && (i < existingConstraints.size()); i++)
+ for (int i = 0; (currentUsedCapabilities != null) && (i < currentUsedCapabilities.size()); i++)
{
- if (!existingConstraints.get(i).m_sources.containsAll(candConstraint.m_sources))
+ if (!currentUsedCapabilities.contains(candCap))
{
throw new ResolveException("Constraint violation for package '" + pkgName
+ "' when resolving module " + current
+ " between existing constraint "
- + existingConstraints.get(i).m_capability.getModule()
- + " " + existingConstraints.get(i).m_sources
- + " and candidate constraint " + candConstraint.m_capability.getModule()
- + " " + candConstraint.m_sources);
+ + current
+ + " " + currentUsedCapabilities
+ + " and candidate constraint " + candCap.getModule()
+ + " " + candCap);
}
}
}
// TODO: PROTO2 RESOLVER - We end up with duplicates in uses constraints,
// see scenario 2 for an example.
- private void verifyUses(
+ private void verifyAndMergeUses(
Module current, Packages currentPkgs,
- Capability candCap, Map<Module, Packages> modulePkgMap,
- String pkgName)
+ Capability candCap, Map<Module, Packages> modulePkgMap)
{
if (m_isInvokeCount)
{
@@ -302,72 +359,73 @@
count = (count == null) ? new Long(1) : new Long(count.longValue() + 1);
m_invokeCounts.put(methodName, count);
}
- Constraint currentExportedConstraint = currentPkgs.m_exportedPkgs.get(pkgName);
- Constraint currentImportedConstraint = currentPkgs.m_importedPkgs.get(pkgName);
- Constraint currentRequiredConstraint = currentPkgs.m_requiredPkgs.get(pkgName);
-
- Packages candPkgs = modulePkgMap.get(candCap.getModule());
- Constraint candConstraint = candPkgs.m_exportedPkgs.get(pkgName);
- candConstraint = (candConstraint != null)
- ? candConstraint
- : candPkgs.m_importedPkgs.get(pkgName);
- candConstraint = (candConstraint != null)
- ? candConstraint
- : candPkgs.m_requiredPkgs.get(pkgName);
-
- // If the candidate doesn't actually have a constraint for
- // the used package, then just ignore it since this is likely
- // an error in its metadata.
- if (candConstraint == null)
- {
- return;
- }
- // If there is no current mapping for this package, then
- // we can just return.
- if ((currentExportedConstraint == null)
- && (currentImportedConstraint == null)
- && (currentRequiredConstraint == null))
+ for (Capability candCapSource : getPackageSources(candCap, modulePkgMap))
{
- List<Constraint> constraints = currentPkgs.m_usedPkgs.get(pkgName);
- if (constraints == null)
+ for (String usedPkgName : candCapSource.getUses())
{
- constraints = new ArrayList<Constraint>();
- currentPkgs.m_usedPkgs.put(pkgName, constraints);
- }
- constraints.add(candConstraint);
- return;
- }
+ Capability currentExportedCap = currentPkgs.m_exportedPkgs.get(usedPkgName);
+ Capability currentImportedCap = currentPkgs.m_importedPkgs.get(usedPkgName);
+ List<Capability> currentRequiredCaps = currentPkgs.m_requiredPkgs.get(usedPkgName);
+
+ Packages sourcePkgs = modulePkgMap.get(candCapSource.getModule());
+ Capability sourceCap = sourcePkgs.m_exportedPkgs.get(usedPkgName);
+ sourceCap = (sourceCap != null)
+ ? sourceCap
+ : sourcePkgs.m_importedPkgs.get(usedPkgName);
+// sourceCap = (sourceCap != null)
+// ? sourceCap
+// : sourcePkgs.m_requiredPkgs.get(usedPkgName);
+
+ // If the candidate doesn't actually have a constraint for
+ // the used package, then just ignore it since this is likely
+ // an error in its metadata.
+ if (sourceCap == null)
+ {
+ return;
+ }
- if ((currentExportedConstraint != null)
- && !currentExportedConstraint.m_sources.containsAll(candConstraint.m_sources))
- {
- throw new ResolveException("Constraint violation for package '" + pkgName
- + "' when resolving module " + current
- + " between existing constraint "
- + currentExportedConstraint.m_capability.getModule()
- + " " + currentExportedConstraint.m_sources
- + " and candidate constraint " + candConstraint.m_capability.getModule()
- + " " + candConstraint.m_sources);
- }
- else if ((currentImportedConstraint != null)
- && !currentImportedConstraint.m_sources.containsAll(candConstraint.m_sources))
- {
- throw new ResolveException("Constraint violation for package '" + pkgName
- + "' when resolving module " + current
- + " between existing constraint "
- + currentImportedConstraint.m_capability.getModule()
- + " " + currentImportedConstraint.m_sources
- + " and candidate constraint " + candConstraint.m_capability.getModule()
- + " " + candConstraint.m_sources);
- }
+ // If there is no current mapping for this package, then
+ // we can just return.
+ if ((currentExportedCap == null)
+ && (currentImportedCap == null)
+ && (currentRequiredCaps == null))
+ {
+ List<Capability> usedCaps = currentPkgs.m_usedPkgs.get(usedPkgName);
+ if (usedCaps == null)
+ {
+ usedCaps = new ArrayList<Capability>();
+ currentPkgs.m_usedPkgs.put(usedPkgName, usedCaps);
+ }
+ usedCaps.add(sourceCap);
+ return;
+ }
- // Verify the candidate's uses constraints do not conflict.
- for (Capability cap : candConstraint.m_sources)
- {
- for (String usedPkg : cap.getUses())
- {
- verifyUses(current, currentPkgs, cap, modulePkgMap, usedPkg);
+ if ((currentExportedCap != null)
+ && !currentExportedCap.equals(sourceCap))
+ {
+ throw new ResolveException("Constraint violation for package '" + usedPkgName
+ + "' when resolving module " + current
+ + " between existing constraint "
+ + currentExportedCap.getModule()
+ + " " + currentExportedCap
+ + " and candidate constraint " + sourceCap.getModule()
+ + " " + sourceCap);
+ }
+ else if ((currentImportedCap != null)
+ && !currentImportedCap.equals(sourceCap))
+ {
+ throw new ResolveException("Constraint violation for package '" + usedPkgName
+ + "' when resolving module " + current
+ + " between existing constraint "
+ + currentImportedCap.getModule()
+ + " " + currentImportedCap
+ + " and candidate constraint " + sourceCap.getModule()
+ + " " + sourceCap);
+ }
+
+ // Verify the candidate's uses constraints do not conflict.
+ verifyAndMergeUses(current, currentPkgs, sourceCap, modulePkgMap);
}
}
}
@@ -507,11 +565,9 @@
if (caps.get(i).getNamespace().equals(Capability.PACKAGE_NAMESPACE)
&& !hasOverlappingImport(module, caps.get(i)))
{
- List<Capability> sources = new ArrayList<Capability>();
- sources.add(caps.get(i));
packages.m_exportedPkgs.put(
(String) caps.get(i).getAttribute(Capability.PACKAGE_ATTR).getValue(),
- new Constraint(caps.get(i), sources));
+ caps.get(i));
}
}
}
@@ -541,16 +597,35 @@
return false;
}
+ private static List<Capability> getPackageSources(
+ Capability cap, Map<Module, Packages> modulePkgMap)
+ {
+ List<Capability> sources = null;
+ if (cap.getNamespace().equals(Capability.PACKAGE_NAMESPACE))
+ {
+ Packages pkgs = modulePkgMap.get(cap.getModule());
+ sources = new ArrayList<Capability>();
+ sources.add(cap);
+ String pkgName = cap.getAttribute(Capability.PACKAGE_ATTR).getValue().toString();
+ List<Capability> required = pkgs.m_requiredPkgs.get(pkgName);
+ if (required != null)
+ {
+ sources.addAll(required);
+ }
+ }
+ return sources;
+ }
+
private class Packages
{
- public final Map<String, Constraint> m_exportedPkgs
- = new HashMap<String, Constraint>();
- public final Map<String, Constraint> m_importedPkgs
- = new HashMap<String, Constraint>();
- public final Map<String, Constraint> m_requiredPkgs
- = new HashMap<String, Constraint>();
- public final Map<String, List<Constraint>> m_usedPkgs
- = new HashMap<String, List<Constraint>>();
+ public final Map<String, Capability> m_exportedPkgs
+ = new HashMap<String, Capability>();
+ public final Map<String, Capability> m_importedPkgs
+ = new HashMap<String, Capability>();
+ public final Map<String, List<Capability>> m_requiredPkgs
+ = new HashMap<String, List<Capability>>();
+ public final Map<String, List<Capability>> m_usedPkgs
+ = new HashMap<String, List<Capability>>();
public Packages()
{
@@ -564,20 +639,4 @@
m_usedPkgs.putAll(packages.m_usedPkgs);
}
}
-
- private class Constraint
- {
- public final Capability m_capability;
- public final List<Capability> m_sources;
- public Constraint(Capability capability, List<Capability> sources)
- {
- m_capability = capability;
- m_sources = sources;
- }
-
- public String toString()
- {
- return m_capability + " SOURCES " + m_sources;
- }
- }
}
\ No newline at end of file