package org.eclipse.osgi.internal.loader.sources;
import java.io.IOException;
import java.net.URL;
import java.util.Collection;
import java.util.Enumeration;
import org.eclipse.osgi.container.ModuleRevision;
import org.eclipse.osgi.container.ModuleWiring;
import org.eclipse.osgi.internal.framework.EquinoxBundle;
import org.eclipse.osgi.internal.framework.EquinoxContainer;
import org.eclipse.osgi.internal.loader.BundleLoader;
import org.eclipse.osgi.internal.loader.SystemBundleLoader;
import org.osgi.framework.Bundle;
import org.osgi.framework.ServiceFactory;
import org.osgi.service.packageadmin.PackageAdmin;
public abstract class PackageSource {
protected final String id;
public PackageSource(String id) {
this.id = id.intern();
}
public String getId() {
return id;
}
public abstract SingleSourcePackage[] getSuppliers();
public boolean compare(PackageSource other) {
return id.equals(other.getId());
}
@Override
public int hashCode() {
return id.hashCode();
}
public boolean isNullSource() {
return false;
}
public abstract Class<?> loadClass(String name) throws ClassNotFoundException;
public abstract URL getResource(String name);
public abstract Enumeration<URL> getResources(String name) throws IOException;
public boolean hasCommonSource(PackageSource other) {
if (other == null)
return false;
if (this == other)
return true;
SingleSourcePackage[] suppliers1 = getSuppliers();
SingleSourcePackage[] suppliers2 = other.getSuppliers();
if (suppliers1 == null || suppliers2 == null)
return false;
for (SingleSourcePackage supplier1 : suppliers1) {
for (SingleSourcePackage supplier2 : suppliers2) {
if (supplier2.equals(supplier1)) {
return true;
}
}
}
return false;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(id).append(" -> ");
SingleSourcePackage[] suppliers = getSuppliers();
if (suppliers == null) {
return builder.append(String.valueOf(null)).toString();
}
builder.append('[');
for (int i = 0; i < suppliers.length; i++) {
if (i > 0) {
builder.append(',');
}
builder.append(suppliers[i].getLoader());
}
builder.append(']');
return builder.toString();
}
public abstract Collection<String> listResources(String path, String filePattern);
public static boolean isServiceAssignableTo(Bundle registrant, Bundle client, String className, Class<?> serviceClass, EquinoxContainer container) {
if (registrant == client) {
return true;
}
String pkgName = BundleLoader.getPackageName(className);
if (pkgName.startsWith("java."))
return true;
BundleLoader producerBL = getBundleLoader(registrant);
if (producerBL == null)
return false;
BundleLoader consumerBL = getBundleLoader(client);
if (consumerBL == null)
return false;
PackageSource consumerSource = consumerBL.getPackageSource(pkgName);
if (consumerSource == null)
return true;
if (container.isBootDelegationPackage(pkgName)) {
Bundle systemBundle = container.getStorage().getModuleContainer().getModule(0).getBundle();
SystemBundleLoader systemLoader = (SystemBundleLoader) getBundleLoader(systemBundle);
if (systemLoader.isExportedPackage(pkgName)) {
return true;
}
}
PackageSource producerSource = producerBL.getPackageSource(pkgName);
if (producerSource == null) {
if (serviceClass != null && ServiceFactory.class.isAssignableFrom(serviceClass)) {
@SuppressWarnings("deprecation")
Bundle bundle = container.getPackageAdmin().getBundle(serviceClass);
if (bundle != null && bundle != registrant)
return true;
}
producerSource = getPackageSource(serviceClass, pkgName, container.getPackageAdmin());
if (producerSource == null)
return false;
}
return producerSource.hasCommonSource(consumerSource);
}
private static PackageSource getPackageSource(Class<?> serviceClass, String pkgName, @SuppressWarnings("deprecation") PackageAdmin packageAdmin) {
if (serviceClass == null)
return null;
@SuppressWarnings("deprecation")
Bundle serviceBundle = packageAdmin.getBundle(serviceClass);
if (serviceBundle == null)
return null;
BundleLoader producerBL = getBundleLoader(serviceBundle);
if (producerBL == null)
return null;
PackageSource producerSource = producerBL.getPackageSource(pkgName);
if (producerSource != null)
return producerSource;
Class<?>[] interfaces = serviceClass.getInterfaces();
for (Class<?> intf : interfaces) {
producerSource = getPackageSource(intf, pkgName, packageAdmin);
if (producerSource != null)
return producerSource;
}
return getPackageSource(serviceClass.getSuperclass(), pkgName, packageAdmin);
}
private static BundleLoader getBundleLoader(Bundle bundle) {
ModuleRevision producer = ((EquinoxBundle) bundle).getModule().getCurrentRevision();
ModuleWiring producerWiring = producer.getWiring();
return producerWiring == null ? null : (BundleLoader) producerWiring.getModuleLoader();
}
}