blob: 9c86374e67e59c38023033bae143b53d38a1dc87 [file] [log] [blame]
package org.eclipse.fx.ide.css.cssext.resolver.osgi;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import org.eclipse.fx.core.Subscription;
import org.eclipse.fx.ide.css.cssext.extapi.registry.CssExtFileWatcher;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.util.tracker.BundleTracker;
public class CssExtBundleTracker extends BundleTracker<Object> implements CssExtFileWatcher<Void> {
private Set<URI> cssExtURIs = new HashSet<>();
private List<Consumer<URI>> addListeners = Collections.synchronizedList(new ArrayList<>());
private List<Consumer<URI>> removeListeners = Collections.synchronizedList(new ArrayList<>());
@Override
public String getId() {
return "osgi-bundles";
}
public CssExtBundleTracker(BundleContext context) {
super(context, Bundle.INSTALLED | Bundle.RESOLVED | Bundle.ACTIVE | Bundle.STARTING | Bundle.STOPPING, null);
}
private static boolean notNull(Object o) {
return o != null;
}
private static URI toURI(URL url) {
try {
return url.toURI();
}
catch (URISyntaxException e) {
}
return null;
}
private Iterable<URI> getCssExt(Bundle bundle) {
String cssExtDefs = (String) bundle.getHeaders().get("CssExt-Definition");
if (cssExtDefs != null) {
return Arrays.stream(cssExtDefs.split(","))
.map(cssExtDef -> bundle.getResource(cssExtDef))
.filter(CssExtBundleTracker::notNull)
.map(CssExtBundleTracker::toURI)
.filter(CssExtBundleTracker::notNull)
.collect(Collectors.toSet());
}
return Collections.emptySet();
}
@Override
public Object addingBundle(Bundle bundle, BundleEvent event) {
for (URI extURI : getCssExt(bundle)) {
cssExtURIs.add(extURI);
for (Consumer<URI> onAdd : addListeners) {
onAdd.accept(extURI);
}
}
return super.addingBundle(bundle, event);
}
@Override
public void removedBundle(Bundle bundle, BundleEvent event, Object object) {
for (URI extURI : getCssExt(bundle)) {
cssExtURIs.remove(extURI);
for (Consumer<URI> onRemove : removeListeners) {
onRemove.accept(extURI);
}
}
super.removedBundle(bundle, event, object);
}
@Override
public Subscription subscribe(Void context, Consumer<URI> onAdd, Consumer<URI> onRemove) {
if (onAdd != null) addListeners.add(onAdd);
if (onRemove != null) removeListeners.add(onRemove);
return new Subscription() {
@Override
public void dispose() {
if (onAdd != null) addListeners.remove(onAdd);
if (onRemove != null) removeListeners.remove(onRemove);
}
};
}
@Override
public Set<URI> getCurrent(Void context) {
return cssExtURIs;
}
}