package org.eclipse.core.internal.runtime;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Map;
import org.eclipse.core.runtime.*;
import org.osgi.framework.Bundle;
public class FindSupport {
public static final String PROP_NL = "osgi.nl";
public static final String PROP_OS = "osgi.os";
public static final String PROP_WS = "osgi.ws";
public static final String PROP_ARCH = "osgi.arch";
private static String[] NL_JAR_VARIANTS = buildNLVariants(Activator.getContext() == null ? System.getProperty(PROP_NL) : Activator.getContext().getProperty(PROP_NL));
private static String[] buildNLVariants(String nl) {
ArrayList<String> result = new ArrayList<>();
IPath base = new Path("nl");
IPath path = new Path(nl.replace('_', '/'));
while (path.segmentCount() > 0) {
result.add(base.append(path).toString());
if (path.segmentCount() > 1)
result.add(base.append(path.toString().replace('/', '_')).toString());
path = path.removeLastSegments(1);
}
return result.toArray(new String[result.size()]);
}
public static URL find(Bundle bundle, IPath path) {
return find(bundle, path, null);
}
public static URL find(Bundle b, IPath path, Map<String, String> override) {
return find(b, path, override, null);
}
public static URL[] findEntries(Bundle bundle, IPath path) {
return findEntries(bundle, path, null);
}
public static URL[] findEntries(Bundle bundle, IPath path, Map<String, String> override) {
ArrayList<URL> results = new ArrayList<>(1);
find(bundle, path, override, results);
return results.toArray(new URL[results.size()]);
}
private static URL find(Bundle b, IPath path, Map<String, String> override, ArrayList<URL> multiple) {
if (path == null)
return null;
URL result = null;
if (path.isEmpty() || path.isRoot()) {
result = findInPlugin(b, Path.EMPTY, multiple);
if (result == null || multiple != null)
result = findInFragments(b, Path.EMPTY, multiple);
return result;
}
String first = path.segment(0);
if (first.charAt(0) != '$') {
result = findInPlugin(b, path, multiple);
if (result == null || multiple != null)
result = findInFragments(b, path, multiple);
return result;
}
IPath rest = path.removeFirstSegments(1);
if (first.equalsIgnoreCase("$nl$"))
return findNL(b, rest, override, multiple);
if (first.equalsIgnoreCase("$os$"))
return findOS(b, rest, override, multiple);
if (first.equalsIgnoreCase("$ws$"))
return findWS(b, rest, override, multiple);
if (first.equalsIgnoreCase("$files$"))
return null;
return null;
}
private static URL findOS(Bundle b, IPath path, Map<String, String> override, ArrayList<URL> multiple) {
String os = null;
if (override != null)
try {
os = override.get("$os$");
} catch (ClassCastException e) {
}
if (os == null)
os = Activator.getContext().getProperty(PROP_OS);
if (os.length() == 0)
return null;
String osArch = null;
if (override != null)
try {
osArch = override.get("$arch$");
} catch (ClassCastException e) {
}
if (osArch == null)
osArch = Activator.getContext().getProperty(PROP_ARCH);
if (osArch.length() == 0)
return null;
URL result = null;
IPath base = new Path("os").append(os).append(osArch);
while (base.segmentCount() != 1) {
IPath filePath = base.append(path);
result = findInPlugin(b, filePath, multiple);
if (result != null && multiple == null)
return result;
result = findInFragments(b, filePath, multiple);
if (result != null && multiple == null)
return result;
base = base.removeLastSegments(1);
}
result = findInPlugin(b, path, multiple);
if (result != null && multiple == null)
return result;
return findInFragments(b, path, multiple);
}
private static URL findWS(Bundle b, IPath path, Map<String, String> override, ArrayList<URL> multiple) {
String ws = null;
if (override != null)
try {
ws = override.get("$ws$");
} catch (ClassCastException e) {
}
if (ws == null)
ws = Activator.getContext().getProperty(PROP_WS);
IPath filePath = new Path("ws").append(ws).append(path);
URL result = findInPlugin(b, filePath, multiple);
if (result != null && multiple == null)
return result;
result = findInFragments(b, filePath, multiple);
if (result != null && multiple == null)
return result;
result = findInPlugin(b, path, multiple);
if (result != null && multiple == null)
return result;
return findInFragments(b, path, multiple);
}
private static URL findNL(Bundle b, IPath path, Map<String, String> override, ArrayList<URL> multiple) {
String nl = null;
String[] nlVariants = null;
if (override != null)
try {
nl = override.get("$nl$");
} catch (ClassCastException e) {
}
nlVariants = nl == null ? NL_JAR_VARIANTS : buildNLVariants(nl);
if (nl != null && nl.length() == 0)
return null;
URL result = null;
for (String nlVariant : nlVariants) {
IPath filePath = new Path(nlVariant).append(path);
result = findInPlugin(b, filePath, multiple);
if (result != null && multiple == null)
return result;
result = findInFragments(b, filePath, multiple);
if (result != null && multiple == null)
return result;
}
result = findInPlugin(b, path, multiple);
if (result != null && multiple == null)
return result;
return findInFragments(b, path, multiple);
}
private static URL findInPlugin(Bundle b, IPath filePath, ArrayList<URL> multiple) {
URL result = b.getEntry(filePath.toString());
if (result != null && multiple != null)
multiple.add(result);
return result;
}
private static URL findInFragments(Bundle b, IPath filePath, ArrayList<URL> multiple) {
Activator activator = Activator.getDefault();
if (activator == null)
return null;
Bundle[] fragments = activator.getFragments(b);
if (fragments == null)
return null;
if (multiple != null)
multiple.ensureCapacity(fragments.length + 1);
for (Bundle fragment : fragments) {
URL fileURL = fragment.getEntry(filePath.toString());
if (fileURL != null) {
if (multiple == null)
return fileURL;
multiple.add(fileURL);
}
}
return null;
}
public static final InputStream openStream(Bundle bundle, IPath file, boolean substituteArgs) throws IOException {
URL url = null;
if (!substituteArgs) {
url = findInPlugin(bundle, file, null);
if (url == null)
url = findInFragments(bundle, file, null);
} else {
url = FindSupport.find(bundle, file);
}
if (url != null)
return url.openStream();
throw new IOException("Cannot find " + file.toString());
}
public static URL find(URL url) {
if (!"platform".equalsIgnoreCase(url.getProtocol()))
return null;
String spec = url.getFile().trim();
Object[] obj = null;
try {
obj = PlatformURLPluginConnection.parse(spec, url);
} catch (IOException e) {
RuntimeLog.log(new Status(IStatus.ERROR, IRuntimeConstants.PI_RUNTIME, "Invalid input url:" + url, e));
return null;
}
Bundle bundle = (Bundle) obj[0];
String path = (String) obj[1];
if ("/".equals(path))
return bundle.getEntry(path);
return find(bundle, new Path(path), null);
}
}