| /******************************************************************************* |
| * 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); |
| } |
| |
| } |