// Get the package.
String pkgName =
Util.getClassPackage(className);
BundleRevision requesterRevision = requester.adapt(BundleRevision.class);
// Get package wiring from service requester.
BundleWire requesterWire = Util.getWire(requesterRevision, pkgName);
// Get package wiring from service provider.
BundleRevision providerRevision = m_bundle.adapt(BundleRevision.class);
BundleWire providerWire = Util.getWire(providerRevision, pkgName);
// There are four situations that may occur here:
// 1. Neither the requester, nor provider have wires for the package.
// 2. The requester does not have a wire for the package.
// 3. The provider does not have a wire for the package.
// 4. Both the requester and provider have a wire for the package.
// For case 1, if the requester does not have access to the class at
// all, we assume it is using reflection and do not filter. If the
// requester does have access to the class, then we make sure it is
// the same class as the service. For case 2, we do not filter if the
// requester is the exporter of the package to which the provider of
// the service is wired. Otherwise, as in case 1, if the requester
// does not have access to the class at all, we do not filter, but if
// it does have access we check if it is the same class accessible to
// the providing revision. For case 3, the provider will not have a wire
// if it is exporting the package, so we determine if the requester
// is wired to it or somehow using the same class. For case 4, we
// simply compare the exporting revisions from the package wiring to
// determine if we need to filter the service reference.
// Case 1: Both requester and provider have no wire.
if ((requesterWire == null) && (providerWire == null))
{
// If requester has no access then true, otherwise service
// registration must have same class as requester.
try
{
Class requestClass =
((BundleWiringImpl) requesterRevision.getWiring())
.getClassByDelegation(className);
allow = getRegistration().isClassAccessible(requestClass);
}
catch (Exception ex)
{
// Requester has no access to the class, so allow it, since
// we assume the requester is using reflection.
allow = true;
}
}
// Case 2: Requester has no wire, but provider does.
else if ((requesterWire == null) && (providerWire != null))
{
// Allow if the requester is the exporter of the provider's wire.
if (providerWire.getProviderWiring().getRevision().equals(requesterRevision))
{
allow = true;
}
// Otherwise, check if the requester has access to the class and,
// if so, if it is the same class as the provider.
else
{
try
{
// Try to load class from requester.
Class requestClass =((BundleWiringImpl)
requesterRevision.getWiring()).getClassByDelegation(className);
try
{
// If requester has access to the class, verify it is the
// same class as the provider.
allow = (((BundleWiringImpl)
providerRevision.getWiring())
.getClassByDelegation(className) == requestClass);
}
catch (Exception ex)
{
allow = false;
}
}
catch (Exception ex)
{
// Requester has no access to the class, so allow it, since
// we assume the requester is using reflection.
allow = true;
}
}
}
// Case 3: Requester has a wire, but provider does not.
else if ((requesterWire != null) && (providerWire == null))
{
// If the provider is the exporter of the requester's package, then check
// if the requester is wired to the latest version of the provider, if so
// then allow else don't (the provider has been updated but not refreshed).
if (((BundleImpl) m_bundle).hasRevision(
requesterWire.getProviderWiring().getRevision()))
{
allow = providerRevision.equals(requesterWire.getProviderWiring().getRevision());
}
// If the provider is not the exporter of the requester's package,
// then try to use the service registration to see if the requester's
// class is accessible.
else
{
try
{
// Load the class from the requesting bundle.
Class requestClass = ((BundleWiringImpl)
requesterRevision.getWiring())
.getClassByDelegation(className);
// Get the service registration and ask it to check
// if the service object is assignable to the requesting
// bundle's class.
allow = getRegistration().isClassAccessible(requestClass);
}
catch (Exception ex)
{
// Filter to be safe.
allow = false;
}
}
}
// Case 4: Both requester and provider have a wire.
else
{
// Include service reference if the wires have the
// same source revision.
allow = providerWire.getProviderWiring().getRevision()
.equals(requesterWire.getProviderWiring().getRevision());
}
return allow;
}