blob: 8dd1205e2bf1b6ddeda94813895c580a47598705 [file] [log] [blame]
package org.eclipse.equinox.internal.p2.touchpoint.eclipse;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.equinox.frameworkadmin.BundleInfo;
import org.eclipse.equinox.frameworkadmin.FrameworkAdmin;
import org.eclipse.equinox.p2.artifact.repository.*;
import org.eclipse.equinox.p2.core.helpers.*;
import org.eclipse.equinox.p2.core.location.AgentLocation;
import org.eclipse.equinox.p2.engine.Profile;
import org.eclipse.equinox.p2.metadata.IArtifactKey;
import org.eclipse.equinox.p2.metadata.TouchpointData;
import org.eclipse.osgi.service.environment.EnvironmentInfo;
import org.eclipse.osgi.util.ManifestElement;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
public class Util {
/**
* TODO "cache" is probably not the right term for this location
*/
private final static String CACHE_PATH = "eclipse.p2.cache"; //$NON-NLS-1$
private final static String CONFIG_FOLDER = "eclipse.configurationFolder"; //$NON-NLS-1$
static AgentLocation getAgentLocation() {
return (AgentLocation) ServiceHelper.getService(Activator.getContext(), AgentLocation.class.getName());
}
static IArtifactRepositoryManager getArtifactRepositoryManager() {
return (IArtifactRepositoryManager) ServiceHelper.getService(Activator.getContext(), IArtifactRepositoryManager.class.getName());
}
static URL getBundlePoolLocation(Profile profile) {
String path = profile.getValue(CACHE_PATH);
if (path == null)
path = Activator.getContext().getProperty(CACHE_PATH);
if (path != null)
try {
// TODO this is a hack for now.
return File.separatorChar == '/' ? new URL("file:" + path) : new URL("file:/" + path); //$NON-NLS-1$ //$NON-NLS-2$
} catch (MalformedURLException e) {
// TODO Do nothing and use the default approach
}
AgentLocation location = getAgentLocation();
if (location == null)
return null;
return location.getDataArea(Activator.ID);
}
static IFileArtifactRepository getBundlePoolRepo(Profile profile) {
URL location = getBundlePoolLocation(profile);
IArtifactRepositoryManager manager = getArtifactRepositoryManager();
IArtifactRepository repository = manager.loadRepository(location, null);
if (repository == null) {
// the given repo location is not an existing repo so we have to create something
// TODO for now create a random repo by default.
String repositoryName = location + " - bundle pool"; //$NON-NLS-1$
repository = manager.createRepository(location, repositoryName, "org.eclipse.equinox.p2.artifact.repository.simpleRepository"); //$NON-NLS-1$
// TODO: do we still need to do this
tagAsImplementation(repository);
}
IFileArtifactRepository bundlePool = (IFileArtifactRepository) repository.getAdapter(IFileArtifactRepository.class);
if (bundlePool == null) {
throw new IllegalArgumentException("BundlePool repository not writeable: " + location); //$NON-NLS-1$
}
return bundlePool;
}
private static URL getDownloadCacheLocation() {
AgentLocation location = getAgentLocation();
return (location != null ? location.getArtifactRepositoryURL() : null);
}
static IFileArtifactRepository getDownloadCacheRepo() {
URL location = getDownloadCacheLocation();
IArtifactRepositoryManager manager = getArtifactRepositoryManager();
IArtifactRepository repository = manager.loadRepository(location, null);
if (repository == null) {
// the given repo location is not an existing repo so we have to create something
// TODO for now create a random repo by default.
String repositoryName = location + " - Agent download cache"; //$NON-NLS-1$
repository = manager.createRepository(location, repositoryName, "org.eclipse.equinox.p2.artifact.repository.simpleRepository"); //$NON-NLS-1$
// TODO: do we still need to do this
tagAsImplementation(repository);
}
IFileArtifactRepository downloadCache = (IFileArtifactRepository) repository.getAdapter(IFileArtifactRepository.class);
if (downloadCache == null) {
throw new IllegalArgumentException("Agent download cache not writeable: " + location); //$NON-NLS-1$
}
return downloadCache;
}
// TODO: Will there be other repositories to tag as implementation? Should this
// method to some utility?
private static void tagAsImplementation(IArtifactRepository repository) {
// if (repository != null && repository.getProperties().getProperty(IRepositoryInfo.IMPLEMENTATION_ONLY_KEY) == null) {
// IWritableRepositoryInfo writableInfo = (IWritableRepositoryInfo) repository.getAdapter(IWritableRepositoryInfo.class);
// if (writableInfo != null) {
// writableInfo.getModifiableProperties().setProperty(IRepositoryInfo.IMPLEMENTATION_ONLY_KEY, Boolean.valueOf(true).toString());
// }
// }
}
static BundleInfo createBundleInfo(File bundleFile, String manifest) {
BundleInfo bundleInfo = new BundleInfo();
try {
bundleInfo.setLocation(bundleFile.toURL().toExternalForm());
} catch (MalformedURLException e) {
e.printStackTrace();
}
bundleInfo.setManifest(manifest);
try {
Headers headers = Headers.parseManifest(new ByteArrayInputStream(manifest.getBytes()));
ManifestElement[] element = ManifestElement.parseHeader("bsn", (String) headers.get(Constants.BUNDLE_SYMBOLICNAME)); //$NON-NLS-1$
bundleInfo.setSymbolicName(element[0].getValue());
bundleInfo.setVersion((String) headers.get(Constants.BUNDLE_VERSION));
} catch (BundleException e) {
e.printStackTrace();
}
return bundleInfo;
}
static File getBundleFile(IArtifactKey artifactKey, boolean isZipped, Profile profile) throws IOException {
if (!isZipped) {
IFileArtifactRepository bundlePool = getBundlePoolRepo(profile);
File bundleJar = bundlePool.getArtifactFile(artifactKey);
return bundleJar;
}
// Handle zipped
IFileArtifactRepository downloadCache = getDownloadCacheRepo();
File bundleJar = downloadCache.getArtifactFile(artifactKey);
if (bundleJar == null)
return null;
File bundleFolder = new File(getBundlePoolLocation(profile).getFile(), "plugins/" + artifactKey.getId() + '_' + artifactKey.getVersion()); //$NON-NLS-1$
if (bundleFolder.exists())
return bundleFolder;
if (!bundleFolder.mkdir())
throw new IOException("Can't create the folder: " + bundleFolder);
FileUtils.unzipFile(bundleJar, bundleFolder);
return bundleFolder;
}
static File getConfigurationFolder(Profile profile) {
String config = profile.getValue(CONFIG_FOLDER);
if (config != null)
return new File(config);
return new File(getInstallFolder(profile), "configuration"); //$NON-NLS-1$
}
static File getInstallFolder(Profile profile) {
return new File(profile.getValue(Profile.PROP_INSTALL_FOLDER));
}
/**
* Returns the name of the Eclipse application launcher.
*/
static String getLauncherName(Profile profile) {
String name = profile.getValue(FrameworkAdmin.SERVICE_PROP_KEY_LAUNCHER_NAME);
if (name != null)
return name;
//create a default name based on platform
//TODO Need a better solution for launcher name branding
EnvironmentInfo info = (EnvironmentInfo) ServiceHelper.getService(Activator.getContext(), EnvironmentInfo.class.getName());
if (info.getOS() == org.eclipse.osgi.service.environment.Constants.OS_WIN32)
return "eclipse.exe"; //$NON-NLS-1$
return "eclipse"; //$NON-NLS-1$
}
static String getManifest(TouchpointData[] data) {
for (int i = 0; i < data.length; i++) {
String manifest = data[i].getInstructions("manifest"); //$NON-NLS-1$
if (manifest != null)
return manifest;
}
return null;
}
public static void initFromManifest(String manifest, BundleInfo bInfo) {
try {
bInfo.setManifest(manifest);
Headers headers = Headers.parseManifest(new ByteArrayInputStream(manifest.getBytes()));
ManifestElement[] element = ManifestElement.parseHeader("bsn", (String) headers.get(Constants.BUNDLE_SYMBOLICNAME)); //$NON-NLS-1$
bInfo.setSymbolicName(element[0].getValue());
bInfo.setVersion((String) headers.get(Constants.BUNDLE_VERSION));
} catch (BundleException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Returns the agent location, if possible as a path relative to the configuration
* directory using the @config.dir substitution variable. AgentLocation will
* substitute this variable with the configuration folder location on startup.
* If the agent location is not a sub-directory of the configuration folder, this
* method simply returns the absolute agent location expressed as a URL.
*/
static String computeRelativeAgentLocation(Profile profile) {
URL agentURL = Util.getAgentLocation().getURL();
//TODO handle proper path/url conversion
IPath agentPath = new Path(agentURL.getPath());
IPath configPath = new Path(Util.getConfigurationFolder(profile).getAbsolutePath());
if (configPath.isPrefixOf(agentPath))
return "@config.dir/" + agentPath.removeFirstSegments(configPath.segmentCount()).makeRelative().setDevice(null); //$NON-NLS-1$
return agentURL.toString();
}
}