bndtools.central.Auxiliary Maven / Gradle / Ivy
The newest version!
package bndtools.central;
import java.io.Closeable;
import java.io.IOException;
import java.util.Deque;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.atomic.AtomicBoolean;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.hooks.weaving.WeavingHook;
import org.osgi.framework.hooks.weaving.WovenClass;
import org.osgi.framework.wiring.BundleWiring;
import org.osgi.util.tracker.BundleTracker;
import aQute.bnd.header.Attrs;
import aQute.bnd.header.Parameters;
import aQute.bnd.osgi.About;
import aQute.bnd.osgi.Constants;
import aQute.bnd.osgi.Verifier;
import aQute.bnd.version.Version;
import aQute.bnd.version.VersionRange;
/**
* This class extends the dynamic imports of bndlib with any exported package
* from OSGi that specifies a 'bnd-plugins' attribute. Its value is either true
* or a version range on the bnd version.
*/
class Auxiliary implements Closeable, WeavingHook {
private final BundleContext context;
private final AtomicBoolean closed = new AtomicBoolean(false);
private final ServiceRegistration hook;
private final BundleTracker tracker;
private final Bundle bndlib;
private final Deque delta = new ConcurrentLinkedDeque<>();
Auxiliary(BundleContext context, Bundle bndlib) {
this.bndlib = bndlib;
this.context = context;
this.tracker = new BundleTracker(context, Bundle.RESOLVED + Bundle.ACTIVE + Bundle.STARTING, null) {
@Override
public Bundle addingBundle(Bundle bundle, BundleEvent event) {
if (!doImport(bundle.getHeaders()
.get(Constants.EXPORT_PACKAGE)))
return null;
return super.addingBundle(bundle, event);
}
};
this.tracker.open();
this.hook = this.context.registerService(WeavingHook.class, this, null);
}
/*
* Parse the exports and see
*/
private boolean doImport(String exports) {
if (closed.get() || exports == null || exports.isEmpty())
return false;
Parameters out = new Parameters();
Parameters p = new Parameters(exports);
for (Entry e : p.entrySet()) {
Attrs attrs = e.getValue();
if (attrs == null)
continue;
String plugins = attrs.get("bnd-plugins");
if (plugins == null)
continue;
if (!(plugins.isEmpty() || "true".equalsIgnoreCase(plugins))) {
if (Verifier.isVersionRange(plugins)) {
VersionRange range = new VersionRange(plugins);
if (!range.includes(About._3_0)) // TODO
continue;
}
}
//
// Ok, matched
//
String v = attrs.getVersion();
if (v == null)
v = "0";
for (Iterator i = attrs.keySet()
.iterator(); i.hasNext();) {
String key = i.next();
if (key.endsWith(":"))
i.remove();
}
if (Verifier.isVersion(v)) {
Version version = new Version(v);
attrs.put("version", new VersionRange(true, version, version, true).toString());
}
out.put(e.getKey(), attrs);
}
if (out.isEmpty())
return false;
delta.offerLast(out.toString());
return true;
}
@Override
public void weave(WovenClass wovenClass) {
if (delta.isEmpty()) {
return;
}
BundleWiring wiring = wovenClass.getBundleWiring();
if (wiring == null)
return;
if (wiring.getBundle() != bndlib)
return;
List dynamicImports = wovenClass.getDynamicImports();
for (String dynamicImport; (dynamicImport = delta.pollFirst()) != null;) {
dynamicImports.add(dynamicImport);
}
}
@Override
public void close() throws IOException {
if (closed.getAndSet(true) == false) {
hook.unregister();
tracker.close();
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy