blob: cf93211d333f82675dad947c18dcf4f13492f2ab [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2014 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.pde.internal.core;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.variables.IStringVariableManager;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.osgi.service.datalocation.Location;
import org.eclipse.pde.core.plugin.TargetPlatform;
import org.eclipse.update.configurator.ConfiguratorUtils;
import org.eclipse.update.configurator.IPlatformConfiguration;
import org.eclipse.update.configurator.IPlatformConfiguration.ISiteEntry;
@SuppressWarnings("deprecation")
// PDE still supports searching the platform.xml for plug-in/feature listings
public class PluginPathFinder {
private static final String URL_PROPERTY = "org.eclipse.update.resolution_url"; //$NON-NLS-1$
private static final String EMPTY_STRING = ""; //$NON-NLS-1$
/**
*
* @param platformHome
* @param linkFile
* @param features false for plugins, true for features
* @return path of plugins or features directory of an extension site
*/
private static String getSitePath(String platformHome, File linkFile, boolean features) {
String prefix = new Path(platformHome).removeLastSegments(1).toString();
Properties properties = new Properties();
try {
FileInputStream fis = new FileInputStream(linkFile);
properties.load(fis);
fis.close();
String path = properties.getProperty("path"); //$NON-NLS-1$
if (path != null) {
if (!new Path(path).isAbsolute())
path = prefix + IPath.SEPARATOR + path;
path += IPath.SEPARATOR + "eclipse" + IPath.SEPARATOR; //$NON-NLS-1$
if (features)
path += "features"; //$NON-NLS-1$
else
path += "plugins"; //$NON-NLS-1$
if (new File(path).exists()) {
return path;
}
}
} catch (IOException e) {
}
return null;
}
/**
*
* @param platformHome
* @param features false for plugin sites, true for feature sites
* @return array of ".../plugins" or ".../features" Files
*/
private static File[] getSites(String platformHome, boolean features) {
HashSet<File> sites = new HashSet<>();
File file = new File(platformHome, features ? "features" : "plugins"); //$NON-NLS-1$ //$NON-NLS-2$
if (!features && !file.exists())
file = new File(platformHome);
if (file.exists())
sites.add(file);
File[] linkFiles = new File(platformHome + IPath.SEPARATOR + "links").listFiles(); //$NON-NLS-1$
if (linkFiles != null) {
for (File linkFile : linkFiles) {
String path = getSitePath(platformHome, linkFile, features);
if (path != null) {
sites.add(new File(path));
}
}
}
// If there is no features/plugins folder and no linked files, try the home location
if (sites.isEmpty()) {
file = new File(platformHome);
if (file.exists()) {
sites.add(file);
}
}
return sites.toArray(new File[sites.size()]);
}
/**
* Attempts to find all plugin paths if the target platform was at the given string location.
* <p>
* Should not be called in PDE. It should only be used to confirm test results match the
* old way of doing things (before ITargetPlatformService).
* </p>
*
* @param platformHome the target platform location
* @param installedOnly whether to check for a bundles.info or another configuration file to
* determine what bundles are installed rather than what bundles simply exist in the plugins folder
* @return list of URL plug-in locations
*/
public static URL[] getPluginPaths(String platformHome, boolean installedOnly) {
// If we don't care about installed bundles, simply scan the location
if (!installedOnly)
return scanLocations(getSites(platformHome, false));
// See if we can find a bundles.info to get installed bundles from
URL[] urls = null;
if (new Path(platformHome).equals(new Path(TargetPlatform.getDefaultLocation()))) {
// Pointing at default install, so use the actual configuration area
Location configArea = Platform.getConfigurationLocation();
if (configArea != null) {
urls = P2Utils.readBundlesTxt(platformHome, configArea.getURL());
// try the shared location (parent)
if (urls == null && configArea.getParentLocation() != null) {
urls = P2Utils.readBundlesTxt(platformHome, configArea.getParentLocation().getURL());
}
}
} else {
// Pointing at a folder, so try to guess the configuration area
File configurationArea = new File(platformHome, "configuration"); //$NON-NLS-1$
if (configurationArea.exists()) {
try {
urls = P2Utils.readBundlesTxt(platformHome, configurationArea.toURL());
} catch (MalformedURLException e) {
PDECore.log(e);
}
}
}
if (urls != null) {
return urls;
}
if (new Path(platformHome).equals(new Path(TargetPlatform.getDefaultLocation())) && !isDevLaunchMode())
return ConfiguratorUtils.getCurrentPlatformConfiguration().getPluginPath();
return getPlatformXMLPaths(platformHome, false);
}
public static URL[] getFeaturePaths(String platformHome) {
return getPlatformXMLPaths(platformHome, true);
}
/**
* Returns a list of file URLs for plug-ins or features found in a platform.xml file or in the default
* directory ("plugins"/"features") if no platform.xml is available.
*
* @param platformHome base location for the installation, used to search for platform.xml
* @param findFeatures if <code>true</code> will return paths to features, otherwise will return paths to plug-ins.
* @return a list of URL paths to plug-ins or features. Possibly empty if the platform.xml had no entries or the default directory had no valid files
*/
public static URL[] getPlatformXMLPaths(String platformHome, boolean findFeatures) {
File file = getPlatformFile(platformHome);
if (file != null) {
try {
String value = new Path(platformHome).toFile().toURL().toExternalForm();
System.setProperty(URL_PROPERTY, value);
try {
IPlatformConfiguration config = ConfiguratorUtils.getPlatformConfiguration(file.toURL());
return getConfiguredSitesPaths(platformHome, config, findFeatures);
} finally {
System.setProperty(URL_PROPERTY, EMPTY_STRING);
}
} catch (MalformedURLException e) {
} catch (IOException e) {
}
}
return scanLocations(getSites(platformHome, findFeatures));
}
/**
* Returns a File object representing the platform.xml or null if the file cannot be found.
* @return File representing platform.xml or <code>null</code>
*/
private static File getPlatformFile(String platformHome) {
String location = System.getProperty("org.eclipse.pde.platform_location"); //$NON-NLS-1$
File file = null;
if (location != null) {
try {
IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager();
location = manager.performStringSubstitution(location);
Path path = new Path(location);
if (path.isAbsolute())
file = path.toFile();
else
file = new File(platformHome, location);
if (file.exists())
return file;
} catch (CoreException e) {
PDECore.log(e);
}
}
file = new File(platformHome, "configuration/org.eclipse.update/platform.xml"); //$NON-NLS-1$
return file.exists() ? file : null;
}
private static URL[] getConfiguredSitesPaths(String platformHome, IPlatformConfiguration configuration, boolean features) {
URL[] installPlugins = scanLocations(new File[] {new File(platformHome, features ? "features" : "plugins")}); //$NON-NLS-1$ //$NON-NLS-2$
URL[] extensionPlugins = getExtensionPluginURLs(configuration, features);
URL[] all = new URL[installPlugins.length + extensionPlugins.length];
System.arraycopy(installPlugins, 0, all, 0, installPlugins.length);
System.arraycopy(extensionPlugins, 0, all, installPlugins.length, extensionPlugins.length);
return all;
}
/**
*
* @param config
* @param features true for features false for plugins
* @return URLs for features or plugins on the site
*/
private static URL[] getExtensionPluginURLs(IPlatformConfiguration config, boolean features) {
ArrayList<URL> extensionPlugins = new ArrayList<>();
IPlatformConfiguration.ISiteEntry[] sites = config.getConfiguredSites();
for (ISiteEntry site : sites) {
URL url = site.getURL();
if ("file".equalsIgnoreCase(url.getProtocol())) { //$NON-NLS-1$
String[] entries;
if (features)
entries = site.getFeatures();
else
entries = site.getPlugins();
for (String entry : entries) {
try {
extensionPlugins.add(new File(url.getFile(), entry).toURL());
} catch (MalformedURLException e) {
}
}
}
}
return extensionPlugins.toArray(new URL[extensionPlugins.size()]);
}
/**
* Scan given plugin/feature directories or jars for existence
* @param sites
* @return URLs to plugins/features
*/
public static URL[] scanLocations(File[] sites) {
HashSet<URL> result = new HashSet<>();
for (int i = 0; i < sites.length; i++) {
if (!sites[i].exists())
continue;
File[] children = sites[i].listFiles();
if (children != null) {
for (File element : children) {
try {
result.add(element.toURL());
} catch (MalformedURLException e) {
}
}
}
}
return result.toArray(new URL[result.size()]);
}
public static boolean isDevLaunchMode() {
if (Boolean.getBoolean("eclipse.pde.launch")) //$NON-NLS-1$
return true;
String[] args = Platform.getApplicationArgs();
for (String arg : args) {
if (arg.equals("-pdelaunch")) //$NON-NLS-1$
return true;
}
return false;
}
}