package org.xpect.ui.util;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.URI;
import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;
import org.xpect.ui.XpectPluginActivator;
import org.xpect.util.IBundleInfo;
import org.xpect.util.ResourceAccess;
import com.google.common.base.Predicate;
import com.google.common.collect.Sets;
public class UIBundleInfoRegistry implements IBundleInfo.Registry {
public static class UIBundleInfo implements IBundleInfo {
private final Bundle bundle;
private final URI locationURI;
public UIBundleInfo(URI locationURI, Bundle bundle) {
super();
this.locationURI = locationURI;
this.bundle = bundle;
}
public List<URI> find(Context context) {
return getInfo().find(context);
}
public URI find(Context context, String fileName) {
return getInfo().find(context, fileName);
}
public List<URI> find(Context context, String path, Predicate<String> matcher, String... fileExtensions) {
return getInfo().find(context, path, matcher, fileExtensions);
}
public Bundle getBundle() {
return bundle;
}
private ResourceAccess.ResourceInfo getInfo() {
return ResourceAccess.create(getRootURI());
}
public URI getRootURI() {
return locationURI;
}
public String getSymbolicName() {
return bundle.getSymbolicName();
}
@Override
public String toString() {
String type = Platform.isFragment(bundle) ? "fragment" : "bundle";
return type + " '" + getSymbolicName() + "' locationURI:" + getRootURI();
}
}
public Collection<String> getAllBundleNames() {
Set<String> result = Sets.newLinkedHashSet();
for (Bundle bundle : XpectPluginActivator.getInstance().getBundle().getBundleContext().getBundles())
result.add(bundle.getSymbolicName());
return result;
}
public IBundleInfo getBundle(Class<?> clazz) {
Bundle bundle = FrameworkUtil.getBundle(clazz);
if (bundle == null)
return null;
URI locationURI = getBundleLocationURI(bundle);
Bundle[] fragments = Platform.getFragments(bundle);
if (fragments == null || fragments.length == 0)
return new UIBundleInfo(locationURI, bundle);
String classURI = getClassURI(clazz).toString();
if (classURI.startsWith(locationURI.toString()))
return new UIBundleInfo(locationURI, bundle);
for (Bundle fragment : fragments) {
URI fragmentURI = getBundleLocationURI(fragment);
if (classURI.startsWith(fragmentURI.toString()))
return new UIBundleInfo(fragmentURI, fragment);
}
return null;
}
public IBundleInfo getBundle(String symbolicName) {
Bundle bundle = Platform.getBundle(symbolicName);
return bundle != null ? new UIBundleInfo(getBundleLocationURI(bundle), bundle) : null;
}
public IBundleInfo getBundle(URI uri) {
return new IBundleInfo.BundleInfo(null, uri);
}
private URI getBundleLocationURI(Bundle bundle) {
try {
URI uri = URI.createURI(FileLocator.resolve(bundle.getEntry("/")).toString());
if (uri.isArchive())
return uri;
File current = new File(uri.toFileString());
while (current != null) {
if (new File(current, "META-INF").isDirectory())
return URI.createFileURI(current.toString()).appendSegment("");
}
return uri;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private URI getClassURI(Class<?> clazz) {
try {
URL resource = clazz.getClassLoader().getResource("/" + clazz.getName().replace('.', '/') + ".class");
URL url = FileLocator.resolve(resource);
return URI.createURI(url.toString());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}