package com.atlassian.labs.speakeasy.util;
import com.atlassian.plugin.osgi.factory.OsgiPlugin;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.Validate;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
*
*/
public class BundleUtil
{
private static final Logger log = LoggerFactory.getLogger(BundleUtil.class);
public static Bundle findBundleForPlugin(BundleContext bundleContext, String pluginKey)
{
for (Bundle bundle : bundleContext.getBundles())
{
String maybePluginKey = (String) bundle.getHeaders().get(OsgiPlugin.ATLASSIAN_PLUGIN_KEY);
if (pluginKey.equals(maybePluginKey))
{
return bundle;
}
}
return null;
}
public static List<String> getPublicBundlePathsRecursive(Bundle bundle, String startPath)
{
Validate.notNull(bundle);
List<String> paths = new ArrayList<String>();
for (String path : getDirContents(bundle, startPath))
{
if (paths.contains(path) || path.startsWith("META-INF"))
{
continue;
}
if (path.endsWith("/"))
{
paths.add(path);
paths.addAll(getPublicBundlePathsRecursive(bundle, path));
}
else
{
paths.add(path);
}
}
return paths;
}
public static String readEntryToString(String path, Bundle bundle) throws IOException
{
URL url = bundle.getEntry(path);
InputStream in = null;
try
{
StringWriter writer = new StringWriter();
in = url.openStream();
IOUtils.copy(in, writer);
return writer.toString();
}
finally
{
IOUtils.closeQuietly(in);
}
}
private static Iterable<String> getDirContents(Bundle bundle, String startPath)
{
List<String> dirs = new ArrayList<String>();
List<String> files = new ArrayList<String>();
Enumeration<String> e = bundle.getEntryPaths(startPath);
while (e != null && e.hasMoreElements())
{
String path = e.nextElement();
if (path.endsWith("/") && !dirs.contains(path))
{
dirs.add(path);
}
else
{
files.add(path);
}
}
Collections.sort(dirs);
Collections.sort(files);
List<String> contents = new ArrayList<String>(dirs);
contents.addAll(files);
return contents;
}
public static Iterable<String> scanForPaths(Bundle bundle, String startPath)
{
return scanForPaths(bundle, startPath, Predicates.<String>alwaysTrue());
}
public static Iterable<String> scanForPaths(Bundle bundle, String startPath, Predicate<String> predicate)
{
Set<String> paths = new HashSet<String>();
scanPath(bundle, startPath, startPath, paths, predicate);
if (paths.isEmpty())
{
log.debug("No resources found at " + startPath + " in bundle " + bundle.getSymbolicName());
}
return paths;
}
private static void scanPath(Bundle bundle, String root, String prefix, Set<String> paths, Predicate<String> predicate)
{
final Enumeration<String> entryPaths = bundle.getEntryPaths(prefix);
while(entryPaths != null && entryPaths.hasMoreElements())
{
String fullPath = entryPaths.nextElement();
if (fullPath.endsWith("/"))
{
scanPath(bundle, root, fullPath, paths, predicate);
}
else
{
String path = fullPath.substring(root.length() - 1);
if (path.startsWith("/"))
{
path = path.substring(1);
}
if (predicate.apply(path))
{
paths.add(path);
}
}
}
}
}