// for any fragments and map a host to all of its fragments.
Map<BundleRevision, List<BundleRevision>> hosts =
new HashMap<BundleRevision, List<BundleRevision>>();
for (Entry<BundleRevision, List<ResolverWire>> entry : wireMap.entrySet())
{
BundleRevision revision = entry.getKey();
List<ResolverWire> wires = entry.getValue();
if (Util.isFragment(revision))
{
for (Iterator<ResolverWire> itWires = wires.iterator();
itWires.hasNext(); )
{
ResolverWire w = itWires.next();
List<BundleRevision> fragments = hosts.get(w.getProvider());
if (fragments == null)
{
fragments = new ArrayList<BundleRevision>();
hosts.put(w.getProvider(), fragments);
}
fragments.add(w.getRequirer());
}
}
}
// Second pass: Loop through the wire map to do three things:
// 1) convert resolver wires to bundle wires 2) create wiring
// objects for revisions and 3) record dependencies among
// revisions. We don't actually set the wirings here because
// that indicates that a revision is resolved and we don't want
// to mark anything as resolved unless we succussfully create
// all wirings.
Map<BundleRevision, BundleWiringImpl> wirings =
new HashMap<BundleRevision, BundleWiringImpl>(wireMap.size());
for (Entry<BundleRevision, List<ResolverWire>> entry : wireMap.entrySet())
{
BundleRevision revision = entry.getKey();
List<ResolverWire> resolverWires = entry.getValue();
List<BundleWire> bundleWires =
new ArrayList<BundleWire>(resolverWires.size());
// Need to special case fragments since they may already have
// wires if they are already attached to another host; if that
// is the case, then we want to merge the old host wires with
// the new ones.
if ((revision.getWiring() != null) && Util.isFragment(revision))
{
// Fragments only have host wires, so just add them all.
bundleWires.addAll(revision.getWiring().getRequiredWires(null));
}
// Loop through resolver wires to calculate the package
// space implied by the wires as well as to record the
// dependencies.
Map<String, BundleRevision> importedPkgs =
new HashMap<String, BundleRevision>();
Map<String, List<BundleRevision>> requiredPkgs =
new HashMap<String, List<BundleRevision>>();
for (ResolverWire rw : resolverWires)
{
BundleWire bw = new BundleWireImpl(
rw.getRequirer(),
rw.getRequirement(),
rw.getProvider(),
rw.getCapability());
bundleWires.add(bw);
if (Util.isFragment(revision))
{
if (debugLog)
{
m_felix.getLogger().log(
Logger.LOG_DEBUG,
"FRAGMENT WIRE: " + rw.toString());
}
}
else
{
if (debugLog)
{
m_felix.getLogger().log(Logger.LOG_DEBUG, "WIRE: " + rw.toString());
}
if (rw.getCapability().getNamespace()
.equals(BundleRevision.PACKAGE_NAMESPACE))
{
importedPkgs.put(
(String) rw.getCapability().getAttributes()
.get(BundleRevision.PACKAGE_NAMESPACE),
rw.getProvider());
}
else if (rw.getCapability().getNamespace()
.equals(BundleRevision.BUNDLE_NAMESPACE))
{
Set<String> pkgs = calculateExportedAndReexportedPackages(
rw.getProvider(),
wireMap,
new HashSet<String>(),
new HashSet<BundleRevision>());
for (String pkg : pkgs)
{
List<BundleRevision> revs = requiredPkgs.get(pkg);
if (revs == null)
{
revs = new ArrayList<BundleRevision>();
requiredPkgs.put(pkg, revs);
}
revs.add(rw.getProvider());
}
}
}
}
List<BundleRevision> fragments = hosts.get(revision);
try
{
wirings.put(
revision,
new BundleWiringImpl(
m_felix.getLogger(),
m_felix.getConfig(),
this,
(BundleRevisionImpl) revision,
fragments,
bundleWires,
importedPkgs,
requiredPkgs));
}
catch (Exception ex)
{
// This is a fatal error, so undo everything and
// throw an exception.
for (Entry<BundleRevision, BundleWiringImpl> wiringEntry
: wirings.entrySet())
{
// Dispose of wiring.
try
{
wiringEntry.getValue().dispose();
}
catch (Exception ex2)
{
// We are in big trouble.
RuntimeException rte = new RuntimeException(
"Unable to clean up resolver failure.", ex2);
m_felix.getLogger().log(
Logger.LOG_ERROR,
rte.getMessage(), ex2);
throw rte;
}
}
ResolveException re = new ResolveException(
"Unable to resolve " + revision,
revision, null);
re.initCause(ex);
m_felix.getLogger().log(
Logger.LOG_ERROR,
re.getMessage(), ex);
throw re;
}
}
// Third pass: Loop through the wire map to mark revision as resolved
// and update the resolver state.
for (Entry<BundleRevision, BundleWiringImpl> entry : wirings.entrySet())
{
BundleRevisionImpl revision = (BundleRevisionImpl) entry.getKey();
// Mark revision as resolved.
BundleWiring wiring = entry.getValue();
revision.resolve(entry.getValue());
// Record dependencies.
for (BundleWire bw : wiring.getRequiredWires(null))
{
m_felix.getDependencies().addDependent(bw);