blob: 03d0133922197e586fcd069e64ce405243932b5c [file] [log] [blame]
/**
*
* Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
*/
package org.eclipse.osbp.infogrid.services;
import java.net.URL;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.eclipse.emf.common.util.URI;
import org.eclipse.osbp.infogrid.api.IGridSourceCache;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.wiring.BundleWiring;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.osgi.util.tracker.BundleTracker;
import org.osgi.util.tracker.BundleTrackerCustomizer;
/**
* OSBP uses ECView files directly and does not derive them from the
* UiDSL-Model. If you have interest using this feature, just provide that class
* as an OSGi service.
*/
@Component(immediate = true)
public class GridSourceCacheBuilder {
private static final String OSBP_MODEL_EXTENDER = "Factory-Model";
@SuppressWarnings("unused")
private ComponentContext context;
private BundleTracker<List<URL>> tracker;
private IGridSourceCache cache;
public GridSourceCacheBuilder() {
}
@Activate
protected void activate(ComponentContext context) {
this.context = context;
tracker = new BundleTracker<>(context.getBundleContext(),
stateCreteria(), new Customizer());
tracker.open();
}
protected int stateCreteria() {
return Bundle.RESOLVED | Bundle.STARTING | Bundle.ACTIVE
| Bundle.STOPPING;
}
@Deactivate
protected void deactivate(ComponentContext context) {
tracker.close();
this.context = null;
}
/**
* Returns true, if the bundle contains the header.
*
* @param bundle
* @param header
* @return
*/
private boolean containsHeader(Bundle bundle, String header) {
Dictionary<String, String> headers = bundle.getHeaders();
Enumeration<String> keys = headers.keys();
while (keys.hasMoreElements()) {
String key = keys.nextElement();
if (key.equals(header)) {
return true;
}
}
return false;
}
/**
* Searches for all ECView translations in the given bundle.
*
* @param bundle
* @return
*/
private List<URL> internalFindURLs(Bundle bundle) {
List<URL> results = new ArrayList<URL>();
BundleWiring wiring = bundle.adapt(BundleWiring.class);
results.addAll(wiring.findEntries("/", "*.gridsource_xmi",
BundleWiring.LISTRESOURCES_RECURSE));
Set<String> fragments = new HashSet<String>();
for (Iterator<URL> iterator = results.iterator(); iterator.hasNext();) {
URL url = iterator.next();
URI uri = URI.createURI(url.toString());
if (fragments.contains(uri.lastSegment())) {
iterator.remove();
}
fragments.add(uri.lastSegment());
}
return results;
}
@Reference(cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.STATIC, unbind = "unbindGridSourceCache")
protected void bindGridSourceCache(IGridSourceCache cache) {
this.cache = cache;
}
protected void unbindGridSourceCache(IGridSourceCache cache) {
this.cache = null;
tracker.close();
tracker = null;
}
private class Customizer implements BundleTrackerCustomizer<List<URL>> {
@Override
public List<URL> addingBundle(Bundle bundle, BundleEvent event) {
if (!containsHeader(bundle, OSBP_MODEL_EXTENDER)) {
return null;
}
List<URL> urls = internalFindURLs(bundle);
cache.registerSources(urls);
return urls;
}
@Override
public void modifiedBundle(Bundle bundle, BundleEvent event,
List<URL> object) {
}
@Override
public void removedBundle(Bundle bundle, BundleEvent event,
List<URL> urls) {
cache.unregisterSources(urls);
}
}
}