blob: 2845963699a49c65d771df3992ee2cef712ca650 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2008 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
* Red Hat Incorporated - fix for bug 225145
*******************************************************************************/
package org.eclipse.equinox.internal.p2.touchpoint.eclipse;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.core.helpers.*;
import org.eclipse.equinox.internal.provisional.frameworkadmin.BundleInfo;
import org.eclipse.equinox.internal.provisional.p2.artifact.repository.*;
import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException;
import org.eclipse.equinox.internal.provisional.p2.core.location.AgentLocation;
import org.eclipse.equinox.internal.provisional.p2.core.repository.IRepository;
import org.eclipse.equinox.internal.provisional.p2.engine.IProfile;
import org.eclipse.equinox.internal.provisional.p2.metadata.IArtifactKey;
import org.eclipse.equinox.internal.provisional.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 CONFIG_FOLDER = "eclipse.configurationFolder"; //$NON-NLS-1$
private static final String REPOSITORY_TYPE = IArtifactRepositoryManager.TYPE_SIMPLE_REPOSITORY;
private static final String CACHE_EXTENSIONS = "org.eclipse.equinox.p2.cache.extensions"; //$NON-NLS-1$
private static final String PIPE = "|"; //$NON-NLS-1$
public static AgentLocation getAgentLocation() {
return (AgentLocation) ServiceHelper.getService(Activator.getContext(), AgentLocation.class.getName());
}
public static IArtifactRepositoryManager getArtifactRepositoryManager() {
return (IArtifactRepositoryManager) ServiceHelper.getService(Activator.getContext(), IArtifactRepositoryManager.class.getName());
}
public static URL getBundlePoolLocation(IProfile profile) {
String path = profile.getProperty(IProfile.PROP_CACHE);
if (path != null)
try {
// TODO this is a hack for now.
return new File(path).toURL();
} 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 public IFileArtifactRepository getBundlePoolRepository(IProfile profile) {
URL location = getBundlePoolLocation(profile);
IArtifactRepositoryManager manager = getArtifactRepositoryManager();
try {
return (IFileArtifactRepository) manager.loadRepository(location, null);
} catch (ProvisionException e) {
//the repository doesn't exist, so fall through and create a new one
}
try {
String repositoryName = Messages.BundlePool;
IArtifactRepository bundlePool = manager.createRepository(location, repositoryName, REPOSITORY_TYPE);
manager.addRepository(bundlePool.getLocation());
bundlePool.setProperty(IRepository.PROP_SYSTEM, Boolean.valueOf(true).toString());
return (IFileArtifactRepository) bundlePool;
} catch (ProvisionException e) {
LogHelper.log(e);
throw new IllegalArgumentException("Bundle pool repository not writeable: " + location); //$NON-NLS-1$
}
}
public static IFileArtifactRepository getAggregatedBundleRepository(IProfile profile) {
Set bundleRepositories = new HashSet();
bundleRepositories.add(Util.getBundlePoolRepository(profile));
IArtifactRepositoryManager manager = getArtifactRepositoryManager();
List extensions = getListProfileProperty(profile, CACHE_EXTENSIONS);
for (Iterator iterator = extensions.iterator(); iterator.hasNext();) {
try {
String extension = (String) iterator.next();
URL extensionURL = new URL(extension);
IArtifactRepository repository = manager.loadRepository(extensionURL, null);
if (repository != null)
bundleRepositories.add(repository);
} catch (ProvisionException e) {
//skip repositories that could not be read
} catch (MalformedURLException e) {
// unexpected, URLs should be pre-checked
LogHelper.log(new Status(IStatus.ERROR, Activator.ID, e.getMessage(), e));
}
}
return new AggregatedBundleRepository(bundleRepositories);
}
private static List getListProfileProperty(IProfile profile, String key) {
List listProperty = new ArrayList();
String dropinRepositories = profile.getProperty(key);
if (dropinRepositories != null) {
StringTokenizer tokenizer = new StringTokenizer(dropinRepositories, PIPE);
while (tokenizer.hasMoreTokens()) {
listProperty.add(tokenizer.nextToken());
}
}
return listProperty;
}
public static BundleInfo createBundleInfo(File bundleFile, String manifest) {
BundleInfo bundleInfo = new BundleInfo();
try {
if (bundleFile != null)
bundleInfo.setLocation(bundleFile.toURL().toExternalForm());
} catch (MalformedURLException e) {
//Ignore since we are creating the URL from the file
}
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$
if (element == null || element.length == 0)
return null;
bundleInfo.setSymbolicName(element[0].getValue());
String version = (String) headers.get(Constants.BUNDLE_VERSION);
if (version == null)
return null;
bundleInfo.setVersion(version);
} catch (BundleException e) {
// unexpected
LogHelper.log(new Status(IStatus.ERROR, Activator.ID, e.getMessage(), e));
return null;
}
return bundleInfo;
}
public static File getArtifactFile(IArtifactKey artifactKey, IProfile profile) {
IFileArtifactRepository aggregatedView = getAggregatedBundleRepository(profile);
File bundleJar = aggregatedView.getArtifactFile(artifactKey);
return bundleJar;
}
public static File getConfigurationFolder(IProfile profile) {
String config = profile.getProperty(CONFIG_FOLDER);
if (config != null)
return new File(config);
return new File(getInstallFolder(profile), "configuration"); //$NON-NLS-1$
}
public static File getInstallFolder(IProfile profile) {
return new File(profile.getProperty(IProfile.PROP_INSTALL_FOLDER));
}
public static File getLauncherPath(IProfile profile) {
return new File(getInstallFolder(profile), getLauncherName(profile));
}
/**
* Returns the name of the Eclipse application launcher.
*/
private static String getLauncherName(IProfile profile) {
String name = profile.getProperty(EclipseTouchpoint.PROFILE_PROP_LAUNCHER_NAME);
String os = getOSFromProfile(profile);
if (os == null) {
EnvironmentInfo info = (EnvironmentInfo) ServiceHelper.getService(Activator.getContext(), EnvironmentInfo.class.getName());
if (info != null)
os = info.getOS();
}
if (name == null)
name = "eclipse"; //$NON-NLS-1$
if (os.equals(org.eclipse.osgi.service.environment.Constants.OS_MACOSX)) {
return name + ".app/Contents/MacOS/" + name.toLowerCase(); //$NON-NLS-1$
}
return name;
}
private static String getOSFromProfile(IProfile profile) {
String environments = profile.getProperty(IProfile.PROP_ENVIRONMENTS);
if (environments == null)
return null;
for (StringTokenizer tokenizer = new StringTokenizer(environments, ","); tokenizer.hasMoreElements();) { //$NON-NLS-1$
String entry = tokenizer.nextToken();
int i = entry.indexOf('=');
String key = entry.substring(0, i).trim();
if (!key.equals("osgi.os")) //$NON-NLS-1$
continue;
return entry.substring(i + 1).trim();
}
return null;
}
public 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 && manifest.length() > 0)
return manifest;
}
return null;
}
/**
* 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.
*/
public static String computeRelativeAgentLocation(IProfile 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$
if (agentPath.removeLastSegments(1).equals(configPath.removeLastSegments(1)))
return "@config.dir/../" + agentPath.lastSegment(); //$NON-NLS-1$
return agentURL.toString();
}
public static IStatus createError(String message) {
return createError(message, null);
}
public static IStatus createError(String message, Exception e) {
return new Status(IStatus.ERROR, Activator.ID, message, e);
}
}