### Eclipse Workspace Patch 1.0 #P org.eclipse.pde.core Index: src/org/eclipse/pde/internal/core/target/impl/ProfileBundleContainer.java =================================================================== RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/impl/ProfileBundleContainer.java,v retrieving revision 1.6 diff -u -r1.6 ProfileBundleContainer.java --- src/org/eclipse/pde/internal/core/target/impl/ProfileBundleContainer.java 21 Jan 2009 20:40:14 -0000 1.6 +++ src/org/eclipse/pde/internal/core/target/impl/ProfileBundleContainer.java 22 Jan 2009 22:27:45 -0000 @@ -1,138 +1,158 @@ -/******************************************************************************* - * Copyright (c) 2008, 2009 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.target.impl; - -import java.net.MalformedURLException; -import java.net.URL; -import org.eclipse.core.runtime.*; -import org.eclipse.equinox.internal.provisional.frameworkadmin.BundleInfo; -import org.eclipse.osgi.util.NLS; -import org.eclipse.pde.internal.core.P2Utils; -import org.eclipse.pde.internal.core.PDECore; - -/** - * A bundle container representing an installed profile. - * - * @since 3.5 - */ -public class ProfileBundleContainer extends AbstractBundleContainer { - - /** - * Constant describing the type of bundle container - */ - public static final String TYPE = "Profile"; //$NON-NLS-1$ - - /** - * Path to home/root install location. May contain string variables. - */ - private String fHome; - - /** - * Alternate configuration location or null if default. - * May contain string variables. - */ - private String fConfiguration; - - /** - * Creates a new bundle container for the profile at the specified location. - * - * @param home path in local file system, may contain string variables - * @param configurationLocation alternate configuration location or null for default, - * may contain string variables - */ - public ProfileBundleContainer(String home, String configurationLocation) { - fHome = home; - fConfiguration = configurationLocation; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#getLocation(boolean) - */ - public String getLocation(boolean resolve) throws CoreException { - if (resolve) { - return resolveHomeLocation().toOSString(); - } - return fHome; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#getType() - */ - public String getType() { - return TYPE; - } - - /** - * Returns the configuration area for this container if one was specified during creation. - * - * @return string path to configuration location or null - */ - public String getConfigurationLocation() { - return fConfiguration; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#resolveAllBundles(org.eclipse.core.runtime.IProgressMonitor) - */ - protected BundleInfo[] resolveAllBundles(IProgressMonitor monitor) throws CoreException { - URL configUrl = getConfigurationArea(); - IPath home = resolveHomeLocation(); - BundleInfo[] infos = P2Utils.readBundles(home.toOSString(), configUrl); - if (infos == null) { - throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.ProfileBundleContainer_0, home.toOSString()))); - } - return infos; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#resolveAllSourceBundles(org.eclipse.core.runtime.IProgressMonitor) - */ - protected BundleInfo[] resolveAllSourceBundles(IProgressMonitor monitor) throws CoreException { - URL configUrl = getConfigurationArea(); - BundleInfo[] source = P2Utils.readSourceBundles(resolveHomeLocation().toOSString(), configUrl); - if (source == null) { - source = new BundleInfo[0]; - } - return source; - } - - /** - * Returns the home location with all variables resolved as a path. - * - * @return resolved home location - * @throws CoreException - */ - private IPath resolveHomeLocation() throws CoreException { - return new Path(resolveVariables(fHome)); - } - - /** - * Returns a URL to the configuration area associated with this profile. - * - * @return configuration area URL - * @throws CoreException if unable to generate a URL - */ - private URL getConfigurationArea() throws CoreException { - IPath home = resolveHomeLocation(); - IPath configuration = null; - if (fConfiguration == null) { - configuration = home.append("configuration"); //$NON-NLS-1$ - } else { - configuration = new Path(resolveVariables(fConfiguration)); - } - try { - return configuration.toFile().toURL(); - } catch (MalformedURLException e) { - throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.ProfileBundleContainer_1, home.toOSString()), e)); - } - } - -} +/******************************************************************************* + * Copyright (c) 2008, 2009 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.target.impl; + +import java.net.MalformedURLException; +import java.net.URL; +import org.eclipse.core.runtime.*; +import org.eclipse.equinox.internal.provisional.frameworkadmin.BundleInfo; +import org.eclipse.osgi.util.NLS; +import org.eclipse.pde.internal.core.P2Utils; +import org.eclipse.pde.internal.core.PDECore; + +/** + * A bundle container representing an installed profile. + * + * @since 3.5 + */ +public class ProfileBundleContainer extends AbstractBundleContainer { + + /** + * Constant describing the type of bundle container + */ + public static final String TYPE = "Profile"; //$NON-NLS-1$ + + /** + * Path to home/root install location. May contain string variables. + */ + private String fHome; + + /** + * Alternate configuration location or null if default. + * May contain string variables. + */ + private String fConfiguration; + + /** + * Creates a new bundle container for the profile at the specified location. + * + * @param home path in local file system, may contain string variables + * @param configurationLocation alternate configuration location or null for default, + * may contain string variables + */ + public ProfileBundleContainer(String home, String configurationLocation) { + fHome = home; + fConfiguration = configurationLocation; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#getLocation(boolean) + */ + public String getLocation(boolean resolve) throws CoreException { + if (resolve) { + return resolveHomeLocation().toOSString(); + } + return fHome; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#getType() + */ + public String getType() { + return TYPE; + } + + /** + * Returns the configuration area for this container if one was specified during creation. + * + * @return string path to configuration location or null + */ + public String getConfigurationLocation() { + return fConfiguration; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#resolveAllBundles(org.eclipse.core.runtime.IProgressMonitor) + */ + protected BundleInfo[] resolveAllBundles(IProgressMonitor monitor) throws CoreException { + URL configUrl = getConfigurationArea(); + IPath home = resolveHomeLocation(); + BundleInfo[] infos = P2Utils.readBundles(home.toOSString(), configUrl); + if (infos == null) { + throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.ProfileBundleContainer_0, home.toOSString()))); + } + return infos; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#resolveAllSourceBundles(org.eclipse.core.runtime.IProgressMonitor) + */ + protected BundleInfo[] resolveAllSourceBundles(IProgressMonitor monitor) throws CoreException { + URL configUrl = getConfigurationArea(); + BundleInfo[] source = P2Utils.readSourceBundles(resolveHomeLocation().toOSString(), configUrl); + if (source == null) { + source = new BundleInfo[0]; + } + return source; + } + + /** + * Returns the home location with all variables resolved as a path. + * + * @return resolved home location + * @throws CoreException + */ + private IPath resolveHomeLocation() throws CoreException { + return new Path(resolveVariables(fHome)); + } + + /** + * Returns a URL to the configuration area associated with this profile. + * + * @return configuration area URL + * @throws CoreException if unable to generate a URL + */ + private URL getConfigurationArea() throws CoreException { + IPath home = resolveHomeLocation(); + IPath configuration = null; + if (fConfiguration == null) { + configuration = home.append("configuration"); //$NON-NLS-1$ + } else { + configuration = new Path(resolveVariables(fConfiguration)); + } + try { + return configuration.toFile().toURL(); + } catch (MalformedURLException e) { + throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.ProfileBundleContainer_1, home.toOSString()), e)); + } + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#isContentEqual(org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer) + */ + public boolean isContentEqual(AbstractBundleContainer container) { + if (container instanceof ProfileBundleContainer) { + ProfileBundleContainer pbc = (ProfileBundleContainer) container; + return fHome.equals(pbc.fHome) && isNullOrEqual(fConfiguration, fConfiguration) && super.isContentEqual(container); + } + return false; + } + + private boolean isNullOrEqual(Object o1, Object o2) { + if (o1 == null) { + return o2 == null; + } + if (o2 == null) { + return false; + } + return o1.equals(o2); + } +} Index: src/org/eclipse/pde/internal/core/target/impl/DirectoryBundleContainer.java =================================================================== RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/impl/DirectoryBundleContainer.java,v retrieving revision 1.6 diff -u -r1.6 DirectoryBundleContainer.java --- src/org/eclipse/pde/internal/core/target/impl/DirectoryBundleContainer.java 21 Jan 2009 20:40:14 -0000 1.6 +++ src/org/eclipse/pde/internal/core/target/impl/DirectoryBundleContainer.java 22 Jan 2009 22:27:45 -0000 @@ -1,307 +1,317 @@ -/******************************************************************************* - * Copyright (c) 2008, 2009 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.target.impl; - -import java.io.*; -import java.util.*; -import java.util.jar.JarFile; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; -import org.eclipse.core.runtime.*; -import org.eclipse.core.runtime.spi.RegistryContributor; -import org.eclipse.equinox.internal.provisional.frameworkadmin.BundleInfo; -import org.eclipse.osgi.service.pluginconversion.PluginConversionException; -import org.eclipse.osgi.service.pluginconversion.PluginConverter; -import org.eclipse.osgi.util.ManifestElement; -import org.eclipse.osgi.util.NLS; -import org.eclipse.pde.internal.core.ICoreConstants; -import org.eclipse.pde.internal.core.PDECore; -import org.osgi.framework.BundleException; -import org.osgi.framework.Constants; - -/** - * A directory of bundles. - * - * @since 3.5 - */ -public class DirectoryBundleContainer extends AbstractBundleContainer { - - /** - * Constant describing the type of bundle container - */ - public static final String TYPE = "Directory"; //$NON-NLS-1$ - - /** - * Path to this container's directory in the local file system. - * The path may contain string substitution variables. - */ - private String fPath; - - /** - * A registry can be built to identify old school source bundles. - */ - private IExtensionRegistry fRegistry; - - /** - * Constructs a directory bundle container at the given location. - * - * @param path directory location in the local file system, may contain string substitution variables - */ - public DirectoryBundleContainer(String path) { - fPath = path; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#getLocation(boolean) - */ - public String getLocation(boolean resolve) throws CoreException { - if (resolve) { - return getDirectory().toString(); - } - return fPath; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#getType() - */ - public String getType() { - return TYPE; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#resolveAllBundles(org.eclipse.core.runtime.IProgressMonitor) - */ - protected BundleInfo[] resolveAllBundles(IProgressMonitor monitor) throws CoreException { - return resolveBundles(monitor, false); - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#resolveAllSourceBundles(org.eclipse.core.runtime.IProgressMonitor) - */ - protected BundleInfo[] resolveAllSourceBundles(IProgressMonitor monitor) throws CoreException { - return resolveBundles(monitor, true); - } - - /** - * Resolves and returns source or code bundles based on the given flag. - * - * @param monitor progress monitor or null - * @param source whether to retrieve source bundles - * @return bundles - * @throws CoreException - */ - private BundleInfo[] resolveBundles(IProgressMonitor monitor, boolean source) throws CoreException { - File dir = getDirectory(); - if (dir.exists() && dir.isDirectory()) { - try { - File[] files = dir.listFiles(); - SubMonitor localMonitor = SubMonitor.convert(monitor, Messages.DirectoryBundleContainer_0, files.length); - List bundles = new ArrayList(files.length); - for (int i = 0; i < files.length; i++) { - if (localMonitor.isCanceled()) { - throw new OperationCanceledException(); - } - Map manifest = loadManifest(files[i]); - if (manifest != null) { - try { - String header = (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME); - if (header != null) { - ManifestElement[] elements = ManifestElement.parseHeader(Constants.BUNDLE_SYMBOLICNAME, header); - if (elements != null) { - String name = elements[0].getValue(); - if (name != null) { - BundleInfo info = new BundleInfo(); - info.setSymbolicName(name); - info.setLocation(files[i].toURI()); - header = (String) manifest.get(Constants.BUNDLE_VERSION); - if (header != null) { - elements = ManifestElement.parseHeader(Constants.BUNDLE_VERSION, header); - if (elements != null) { - info.setVersion(elements[0].getValue()); - } - } - if (source == isSourceBundle(files[i], name, manifest)) { - bundles.add(info); - } - } - } - } - } catch (BundleException e) { - // ignore invalid bundles - } - } - localMonitor.worked(1); - } - localMonitor.done(); - return (BundleInfo[]) bundles.toArray(new BundleInfo[bundles.size()]); - } finally { - if (fRegistry != null) { - fRegistry.stop(this); - fRegistry = null; - } - } - } - throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.DirectoryBundleContainer_1, dir.toString()))); - } - - /** - * Returns whether the given bundle is a source bundle. - * - * @param bundle location of the bundle in the file system - * @param symbolicName symbolic name of the bundle - * @param manifest the bundle's manifest - * @return whether the given bundle is a source bundle - */ - private boolean isSourceBundle(File bundle, String symbolicName, Map manifest) { - if (manifest.containsKey(ICoreConstants.ECLIPSE_SOURCE_BUNDLE)) { - // this is the new source bundle identifier - return true; - } - // old source bundles were never jar'd - if (bundle.isFile()) { - return false; - } - // source bundles never have a class path - if (manifest.containsKey(Constants.BUNDLE_CLASSPATH)) { - return false; - } - // check for an "org.eclipse.pde.core.source" extension - File pxml = new File(bundle, ICoreConstants.PLUGIN_FILENAME_DESCRIPTOR); - if (pxml.exists()) { - IExtensionRegistry registry = getRegistry(); - RegistryContributor contributor = new RegistryContributor(symbolicName, symbolicName, null, null); - try { - registry.addContribution(new BufferedInputStream(new FileInputStream(pxml)), contributor, false, null, null, this); - IExtension[] extensions = registry.getExtensions(contributor); - for (int i = 0; i < extensions.length; i++) { - IExtension extension = extensions[i]; - if (ICoreConstants.EXTENSION_POINT_SOURCE.equals(extension.getExtensionPointUniqueIdentifier())) { - return true; - } - } - } catch (FileNotFoundException e) { - } - } - return false; - } - - /** - * Returns an extension registry used to identify source bundles. - * - * @return extension registry - */ - private IExtensionRegistry getRegistry() { - if (fRegistry == null) { - fRegistry = RegistryFactory.createRegistry(null, this, this); - // contribute PDE source extension point - String bogusDef = "\n\n\n"; //$NON-NLS-1$ - RegistryContributor contributor = new RegistryContributor(PDECore.PLUGIN_ID, PDECore.PLUGIN_ID, null, null); - fRegistry.addContribution(new ByteArrayInputStream(bogusDef.getBytes()), contributor, false, null, null, this); - } - return fRegistry; - } - - /** - * Returns the directory to search for bundles in. - * - * @return directory if unable to resolve variables in the path - */ - protected File getDirectory() throws CoreException { - String path = resolveVariables(fPath); - return new File(path); - } - - /** - * Parses a bunlde's manifest into a dictionary. The bundle may be in a jar - * or in a directory at the specified location. - * - * @param bundleLocation root location of the bundle - * @return bundle manifest dictionary or null if none - * @throws CoreException if manifest has invalid syntax - */ - protected Map loadManifest(File bundleLocation) throws CoreException { - ZipFile jarFile = null; - InputStream manifestStream = null; - String extension = new Path(bundleLocation.getName()).getFileExtension(); - try { - if (extension != null && extension.equals("jar") && bundleLocation.isFile()) { //$NON-NLS-1$ - jarFile = new ZipFile(bundleLocation, ZipFile.OPEN_READ); - ZipEntry manifestEntry = jarFile.getEntry(JarFile.MANIFEST_NAME); - if (manifestEntry != null) { - manifestStream = jarFile.getInputStream(manifestEntry); - } - } else { - File file = new File(bundleLocation, JarFile.MANIFEST_NAME); - if (file.exists()) { - manifestStream = new FileInputStream(file); - } else { - File pxml = new File(bundleLocation, ICoreConstants.PLUGIN_FILENAME_DESCRIPTOR); - File fxml = new File(bundleLocation, ICoreConstants.FRAGMENT_FILENAME_DESCRIPTOR); - if (pxml.exists() || fxml.exists()) { - // support classic non-OSGi plug-in - PluginConverter converter = (PluginConverter) PDECore.getDefault().acquireService(PluginConverter.class.getName()); - if (converter != null) { - try { - Dictionary convert = converter.convertManifest(bundleLocation, false, null, false, null); - if (convert != null) { - Map map = new HashMap(convert.size(), 1.0f); - Enumeration keys = convert.keys(); - while (keys.hasMoreElements()) { - Object key = keys.nextElement(); - map.put(key, convert.get(key)); - } - return map; - } - } catch (PluginConversionException e) { - throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.DirectoryBundleContainer_2, bundleLocation.getAbsolutePath()), e)); - } - } - } - } - } - if (manifestStream == null) { - return null; - } - return ManifestElement.parseBundleManifest(manifestStream, new Hashtable(10)); - } catch (BundleException e) { - PDECore.log(e); - } catch (IOException e) { - throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.DirectoryBundleContainer_3, bundleLocation.getAbsolutePath()), e)); - } finally { - closeZipFileAndStream(manifestStream, jarFile); - } - return null; - } - - /** - * Closes the stream and jar file if not null. - * - * @param stream stream to close or null - * @param jarFile jar to close or null - */ - private void closeZipFileAndStream(InputStream stream, ZipFile jarFile) { - try { - if (stream != null) { - stream.close(); - } - } catch (IOException e) { - PDECore.log(e); - } - try { - if (jarFile != null) { - jarFile.close(); - } - } catch (IOException e) { - PDECore.log(e); - } - } - -} +/******************************************************************************* + * Copyright (c) 2008, 2009 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.target.impl; + +import java.io.*; +import java.util.*; +import java.util.jar.JarFile; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import org.eclipse.core.runtime.*; +import org.eclipse.core.runtime.spi.RegistryContributor; +import org.eclipse.equinox.internal.provisional.frameworkadmin.BundleInfo; +import org.eclipse.osgi.service.pluginconversion.PluginConversionException; +import org.eclipse.osgi.service.pluginconversion.PluginConverter; +import org.eclipse.osgi.util.ManifestElement; +import org.eclipse.osgi.util.NLS; +import org.eclipse.pde.internal.core.ICoreConstants; +import org.eclipse.pde.internal.core.PDECore; +import org.osgi.framework.BundleException; +import org.osgi.framework.Constants; + +/** + * A directory of bundles. + * + * @since 3.5 + */ +public class DirectoryBundleContainer extends AbstractBundleContainer { + + /** + * Constant describing the type of bundle container + */ + public static final String TYPE = "Directory"; //$NON-NLS-1$ + + /** + * Path to this container's directory in the local file system. + * The path may contain string substitution variables. + */ + private String fPath; + + /** + * A registry can be built to identify old school source bundles. + */ + private IExtensionRegistry fRegistry; + + /** + * Constructs a directory bundle container at the given location. + * + * @param path directory location in the local file system, may contain string substitution variables + */ + public DirectoryBundleContainer(String path) { + fPath = path; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#getLocation(boolean) + */ + public String getLocation(boolean resolve) throws CoreException { + if (resolve) { + return getDirectory().toString(); + } + return fPath; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#getType() + */ + public String getType() { + return TYPE; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#resolveAllBundles(org.eclipse.core.runtime.IProgressMonitor) + */ + protected BundleInfo[] resolveAllBundles(IProgressMonitor monitor) throws CoreException { + return resolveBundles(monitor, false); + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#resolveAllSourceBundles(org.eclipse.core.runtime.IProgressMonitor) + */ + protected BundleInfo[] resolveAllSourceBundles(IProgressMonitor monitor) throws CoreException { + return resolveBundles(monitor, true); + } + + /** + * Resolves and returns source or code bundles based on the given flag. + * + * @param monitor progress monitor or null + * @param source whether to retrieve source bundles + * @return bundles + * @throws CoreException + */ + private BundleInfo[] resolveBundles(IProgressMonitor monitor, boolean source) throws CoreException { + File dir = getDirectory(); + if (dir.exists() && dir.isDirectory()) { + try { + File[] files = dir.listFiles(); + SubMonitor localMonitor = SubMonitor.convert(monitor, Messages.DirectoryBundleContainer_0, files.length); + List bundles = new ArrayList(files.length); + for (int i = 0; i < files.length; i++) { + if (localMonitor.isCanceled()) { + throw new OperationCanceledException(); + } + Map manifest = loadManifest(files[i]); + if (manifest != null) { + try { + String header = (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME); + if (header != null) { + ManifestElement[] elements = ManifestElement.parseHeader(Constants.BUNDLE_SYMBOLICNAME, header); + if (elements != null) { + String name = elements[0].getValue(); + if (name != null) { + BundleInfo info = new BundleInfo(); + info.setSymbolicName(name); + info.setLocation(files[i].toURI()); + header = (String) manifest.get(Constants.BUNDLE_VERSION); + if (header != null) { + elements = ManifestElement.parseHeader(Constants.BUNDLE_VERSION, header); + if (elements != null) { + info.setVersion(elements[0].getValue()); + } + } + if (source == isSourceBundle(files[i], name, manifest)) { + bundles.add(info); + } + } + } + } + } catch (BundleException e) { + // ignore invalid bundles + } + } + localMonitor.worked(1); + } + localMonitor.done(); + return (BundleInfo[]) bundles.toArray(new BundleInfo[bundles.size()]); + } finally { + if (fRegistry != null) { + fRegistry.stop(this); + fRegistry = null; + } + } + } + throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.DirectoryBundleContainer_1, dir.toString()))); + } + + /** + * Returns whether the given bundle is a source bundle. + * + * @param bundle location of the bundle in the file system + * @param symbolicName symbolic name of the bundle + * @param manifest the bundle's manifest + * @return whether the given bundle is a source bundle + */ + private boolean isSourceBundle(File bundle, String symbolicName, Map manifest) { + if (manifest.containsKey(ICoreConstants.ECLIPSE_SOURCE_BUNDLE)) { + // this is the new source bundle identifier + return true; + } + // old source bundles were never jar'd + if (bundle.isFile()) { + return false; + } + // source bundles never have a class path + if (manifest.containsKey(Constants.BUNDLE_CLASSPATH)) { + return false; + } + // check for an "org.eclipse.pde.core.source" extension + File pxml = new File(bundle, ICoreConstants.PLUGIN_FILENAME_DESCRIPTOR); + if (pxml.exists()) { + IExtensionRegistry registry = getRegistry(); + RegistryContributor contributor = new RegistryContributor(symbolicName, symbolicName, null, null); + try { + registry.addContribution(new BufferedInputStream(new FileInputStream(pxml)), contributor, false, null, null, this); + IExtension[] extensions = registry.getExtensions(contributor); + for (int i = 0; i < extensions.length; i++) { + IExtension extension = extensions[i]; + if (ICoreConstants.EXTENSION_POINT_SOURCE.equals(extension.getExtensionPointUniqueIdentifier())) { + return true; + } + } + } catch (FileNotFoundException e) { + } + } + return false; + } + + /** + * Returns an extension registry used to identify source bundles. + * + * @return extension registry + */ + private IExtensionRegistry getRegistry() { + if (fRegistry == null) { + fRegistry = RegistryFactory.createRegistry(null, this, this); + // contribute PDE source extension point + String bogusDef = "\n\n\n"; //$NON-NLS-1$ + RegistryContributor contributor = new RegistryContributor(PDECore.PLUGIN_ID, PDECore.PLUGIN_ID, null, null); + fRegistry.addContribution(new ByteArrayInputStream(bogusDef.getBytes()), contributor, false, null, null, this); + } + return fRegistry; + } + + /** + * Returns the directory to search for bundles in. + * + * @return directory if unable to resolve variables in the path + */ + protected File getDirectory() throws CoreException { + String path = resolveVariables(fPath); + return new File(path); + } + + /** + * Parses a bunlde's manifest into a dictionary. The bundle may be in a jar + * or in a directory at the specified location. + * + * @param bundleLocation root location of the bundle + * @return bundle manifest dictionary or null if none + * @throws CoreException if manifest has invalid syntax + */ + protected Map loadManifest(File bundleLocation) throws CoreException { + ZipFile jarFile = null; + InputStream manifestStream = null; + String extension = new Path(bundleLocation.getName()).getFileExtension(); + try { + if (extension != null && extension.equals("jar") && bundleLocation.isFile()) { //$NON-NLS-1$ + jarFile = new ZipFile(bundleLocation, ZipFile.OPEN_READ); + ZipEntry manifestEntry = jarFile.getEntry(JarFile.MANIFEST_NAME); + if (manifestEntry != null) { + manifestStream = jarFile.getInputStream(manifestEntry); + } + } else { + File file = new File(bundleLocation, JarFile.MANIFEST_NAME); + if (file.exists()) { + manifestStream = new FileInputStream(file); + } else { + File pxml = new File(bundleLocation, ICoreConstants.PLUGIN_FILENAME_DESCRIPTOR); + File fxml = new File(bundleLocation, ICoreConstants.FRAGMENT_FILENAME_DESCRIPTOR); + if (pxml.exists() || fxml.exists()) { + // support classic non-OSGi plug-in + PluginConverter converter = (PluginConverter) PDECore.getDefault().acquireService(PluginConverter.class.getName()); + if (converter != null) { + try { + Dictionary convert = converter.convertManifest(bundleLocation, false, null, false, null); + if (convert != null) { + Map map = new HashMap(convert.size(), 1.0f); + Enumeration keys = convert.keys(); + while (keys.hasMoreElements()) { + Object key = keys.nextElement(); + map.put(key, convert.get(key)); + } + return map; + } + } catch (PluginConversionException e) { + throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.DirectoryBundleContainer_2, bundleLocation.getAbsolutePath()), e)); + } + } + } + } + } + if (manifestStream == null) { + return null; + } + return ManifestElement.parseBundleManifest(manifestStream, new Hashtable(10)); + } catch (BundleException e) { + PDECore.log(e); + } catch (IOException e) { + throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.DirectoryBundleContainer_3, bundleLocation.getAbsolutePath()), e)); + } finally { + closeZipFileAndStream(manifestStream, jarFile); + } + return null; + } + + /** + * Closes the stream and jar file if not null. + * + * @param stream stream to close or null + * @param jarFile jar to close or null + */ + private void closeZipFileAndStream(InputStream stream, ZipFile jarFile) { + try { + if (stream != null) { + stream.close(); + } + } catch (IOException e) { + PDECore.log(e); + } + try { + if (jarFile != null) { + jarFile.close(); + } + } catch (IOException e) { + PDECore.log(e); + } + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#isContentEqual(org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer) + */ + public boolean isContentEqual(AbstractBundleContainer container) { + if (container instanceof DirectoryBundleContainer) { + DirectoryBundleContainer dbc = (DirectoryBundleContainer) container; + return fPath.equals(dbc.fPath) && super.isContentEqual(container); + } + return false; + } +} Index: src/org/eclipse/pde/internal/core/target/impl/TargetDefinition.java =================================================================== RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/impl/TargetDefinition.java,v retrieving revision 1.6 diff -u -r1.6 TargetDefinition.java --- src/org/eclipse/pde/internal/core/target/impl/TargetDefinition.java 22 Jan 2009 21:45:19 -0000 1.6 +++ src/org/eclipse/pde/internal/core/target/impl/TargetDefinition.java 22 Jan 2009 22:27:45 -0000 @@ -1,324 +1,396 @@ -/******************************************************************************* - * Copyright (c) 2008, 2009 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.target.impl; - -import java.io.*; -import java.util.*; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.TransformerException; -import org.eclipse.core.runtime.*; -import org.eclipse.equinox.internal.provisional.frameworkadmin.BundleInfo; -import org.eclipse.pde.internal.core.PDECore; -import org.eclipse.pde.internal.core.target.provisional.*; -import org.xml.sax.SAXException; - -/** - * Target definition implementation. - * - * @since 3.5 - */ -class TargetDefinition implements ITargetDefinition { - - // name and description - private String fName; - private String fDescription; - - // arguments - private String fProgramArgs; - private String fVMArgs; - - // environment settings - private IPath fJREContainer; - private String fArch; - private String fOS; - private String fWS; - private String fNL; - - // bundle containers - private IBundleContainer[] fContainers; - - // handle - private ITargetHandle fHandle; - - // implicit dependencies - private BundleInfo[] fImplicit; - - /** - * Constructs a target definition based on the given handle. - */ - TargetDefinition(ITargetHandle handle) { - fHandle = handle; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#getArch() - */ - public String getArch() { - return fArch; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#getBundleContainers() - */ - public IBundleContainer[] getBundleContainers() { - return fContainers; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#getDescription() - */ - public String getDescription() { - return fDescription; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#getNL() - */ - public String getNL() { - return fNL; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#getName() - */ - public String getName() { - return fName; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#getOS() - */ - public String getOS() { - return fOS; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#getProgramArguments() - */ - public String getProgramArguments() { - return fProgramArgs; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#getVMArguments() - */ - public String getVMArguments() { - return fVMArgs; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#getWS() - */ - public String getWS() { - return fWS; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setArch(java.lang.String) - */ - public void setArch(String arch) { - fArch = arch; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setDescription(java.lang.String) - */ - public void setDescription(String description) { - fDescription = description; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setNL(java.lang.String) - */ - public void setNL(String nl) { - fNL = nl; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setName(java.lang.String) - */ - public void setName(String name) { - fName = name; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setOS(java.lang.String) - */ - public void setOS(String os) { - fOS = os; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setProgramArguments(java.lang.String) - */ - public void setProgramArguments(String args) { - fProgramArgs = args; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setVMArguments(java.lang.String) - */ - public void setVMArguments(String args) { - fVMArgs = args; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setWS(java.lang.String) - */ - public void setWS(String ws) { - fWS = ws; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setBundleContainers(org.eclipse.pde.internal.core.target.provisional.IBundleContainer[]) - */ - public void setBundleContainers(IBundleContainer[] containers) { - fContainers = containers; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#resolveBundles(org.eclipse.core.runtime.IProgressMonitor) - */ - public BundleInfo[] resolveBundles(IProgressMonitor monitor) throws CoreException { - IBundleContainer[] containers = getBundleContainers(); - List bundles = new ArrayList(); - if (containers != null) { - for (int i = 0; i < containers.length; i++) { - BundleInfo[] infos = containers[i].resolveBundles(monitor); - bundles.addAll(Arrays.asList(infos)); - } - } - return (BundleInfo[]) bundles.toArray(new BundleInfo[bundles.size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#resolveSourceBundles(org.eclipse.core.runtime.IProgressMonitor) - */ - public BundleInfo[] resolveSourceBundles(IProgressMonitor monitor) throws CoreException { - IBundleContainer[] containers = getBundleContainers(); - List source = new ArrayList(); - if (containers != null) { - for (int i = 0; i < containers.length; i++) { - BundleInfo[] infos = containers[i].resolveSourceBundles(monitor); - source.addAll(Arrays.asList(infos)); - } - } - return (BundleInfo[]) source.toArray(new BundleInfo[source.size()]); - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#getHandle() - */ - public ITargetHandle getHandle() { - return fHandle; - } - - /** - * Build contents from the given stream. - * - * @param stream input stream - * @throws CoreException if an error occurs - */ - void setContents(InputStream stream) throws CoreException { - try { - fArch = null; - fContainers = null; - fDescription = null; - fImplicit = null; - fJREContainer = null; - fName = null; - fNL = null; - fOS = null; - fProgramArgs = null; - fVMArgs = null; - fWS = null; - TargetDefinitionPersistenceHelper.initFromXML(this, stream); - } catch (ParserConfigurationException e) { - abort(Messages.TargetDefinition_0, e); - } catch (SAXException e) { - abort(Messages.TargetDefinition_0, e); - } catch (IOException e) { - abort(Messages.TargetDefinition_0, e); - } - } - - /** - * Persists contents to the given stream. - * - * @param stream output stream - * @throws CoreException if an error occurs - */ - void write(OutputStream stream) throws CoreException { - try { - TargetDefinitionPersistenceHelper.persistXML(this, stream); - } catch (IOException e) { - abort(Messages.TargetDefinition_3, e); - } catch (ParserConfigurationException e) { - abort(Messages.TargetDefinition_3, e); - } catch (TransformerException e) { - abort(Messages.TargetDefinition_3, e); - } - } - - /** - * Throws a core exception with the given message and underlying exception (possibly - * null). - * - * @param message message - * @param e underlying cause of the exception or null - * @throws CoreException - */ - private void abort(String message, Exception e) throws CoreException { - throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, message, e)); - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#getImplicitDependencies() - */ - public BundleInfo[] getImplicitDependencies() { - return fImplicit; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#resolveImplicitDependencies(org.eclipse.core.runtime.IProgressMonitor) - */ - public BundleInfo[] resolveImplicitDependencies(IProgressMonitor monitor) throws CoreException { - int size = 0; - if (fImplicit != null) { - size = fImplicit.length; - } - if (size == 0) { - return new BundleInfo[0]; - } - return AbstractBundleContainer.getMatchingBundles(resolveBundles(null), fImplicit); - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setImplicitDependencies(org.eclipse.equinox.internal.provisional.frameworkadmin.BundleInfo[]) - */ - public void setImplicitDependencies(BundleInfo[] bundles) { - fImplicit = bundles; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#getJREContainer() - */ - public IPath getJREContainer() { - return fJREContainer; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setJREContainer(org.eclipse.core.runtime.IPath) - */ - public void setJREContainer(IPath containerPath) { - fJREContainer = containerPath; - } -} +/******************************************************************************* + * Copyright (c) 2008, 2009 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.target.impl; + +import java.io.*; +import java.util.*; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; +import org.eclipse.core.runtime.*; +import org.eclipse.equinox.internal.provisional.frameworkadmin.BundleInfo; +import org.eclipse.pde.internal.core.PDECore; +import org.eclipse.pde.internal.core.target.provisional.*; +import org.xml.sax.SAXException; + +/** + * Target definition implementation. + * + * @since 3.5 + */ +public class TargetDefinition implements ITargetDefinition { + + // name and description + private String fName; + private String fDescription; + + // arguments + private String fProgramArgs; + private String fVMArgs; + + // environment settings + private IPath fJREContainer; + private String fArch; + private String fOS; + private String fWS; + private String fNL; + + // bundle containers + private IBundleContainer[] fContainers; + + // handle + private ITargetHandle fHandle; + + // implicit dependencies + private BundleInfo[] fImplicit; + + /** + * Constructs a target definition based on the given handle. + */ + TargetDefinition(ITargetHandle handle) { + fHandle = handle; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#getArch() + */ + public String getArch() { + return fArch; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#getBundleContainers() + */ + public IBundleContainer[] getBundleContainers() { + return fContainers; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#getDescription() + */ + public String getDescription() { + return fDescription; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#getNL() + */ + public String getNL() { + return fNL; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#getName() + */ + public String getName() { + return fName; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#getOS() + */ + public String getOS() { + return fOS; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#getProgramArguments() + */ + public String getProgramArguments() { + return fProgramArgs; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#getVMArguments() + */ + public String getVMArguments() { + return fVMArgs; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#getWS() + */ + public String getWS() { + return fWS; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setArch(java.lang.String) + */ + public void setArch(String arch) { + fArch = arch; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setDescription(java.lang.String) + */ + public void setDescription(String description) { + fDescription = description; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setNL(java.lang.String) + */ + public void setNL(String nl) { + fNL = nl; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setName(java.lang.String) + */ + public void setName(String name) { + fName = name; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setOS(java.lang.String) + */ + public void setOS(String os) { + fOS = os; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setProgramArguments(java.lang.String) + */ + public void setProgramArguments(String args) { + fProgramArgs = args; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setVMArguments(java.lang.String) + */ + public void setVMArguments(String args) { + fVMArgs = args; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setWS(java.lang.String) + */ + public void setWS(String ws) { + fWS = ws; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setBundleContainers(org.eclipse.pde.internal.core.target.provisional.IBundleContainer[]) + */ + public void setBundleContainers(IBundleContainer[] containers) { + if (containers != null && containers.length == 0) { + containers = null; + } + fContainers = containers; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#resolveBundles(org.eclipse.core.runtime.IProgressMonitor) + */ + public BundleInfo[] resolveBundles(IProgressMonitor monitor) throws CoreException { + IBundleContainer[] containers = getBundleContainers(); + List bundles = new ArrayList(); + if (containers != null) { + for (int i = 0; i < containers.length; i++) { + BundleInfo[] infos = containers[i].resolveBundles(monitor); + bundles.addAll(Arrays.asList(infos)); + } + } + return (BundleInfo[]) bundles.toArray(new BundleInfo[bundles.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#resolveSourceBundles(org.eclipse.core.runtime.IProgressMonitor) + */ + public BundleInfo[] resolveSourceBundles(IProgressMonitor monitor) throws CoreException { + IBundleContainer[] containers = getBundleContainers(); + List source = new ArrayList(); + if (containers != null) { + for (int i = 0; i < containers.length; i++) { + BundleInfo[] infos = containers[i].resolveSourceBundles(monitor); + source.addAll(Arrays.asList(infos)); + } + } + return (BundleInfo[]) source.toArray(new BundleInfo[source.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#getHandle() + */ + public ITargetHandle getHandle() { + return fHandle; + } + + /** + * Build contents from the given stream. + * + * @param stream input stream + * @throws CoreException if an error occurs + */ + void setContents(InputStream stream) throws CoreException { + try { + fArch = null; + fContainers = null; + fDescription = null; + fImplicit = null; + fJREContainer = null; + fName = null; + fNL = null; + fOS = null; + fProgramArgs = null; + fVMArgs = null; + fWS = null; + TargetDefinitionPersistenceHelper.initFromXML(this, stream); + } catch (ParserConfigurationException e) { + abort(Messages.TargetDefinition_0, e); + } catch (SAXException e) { + abort(Messages.TargetDefinition_0, e); + } catch (IOException e) { + abort(Messages.TargetDefinition_0, e); + } + } + + /** + * Persists contents to the given stream. + * + * @param stream output stream + * @throws CoreException if an error occurs + */ + void write(OutputStream stream) throws CoreException { + try { + TargetDefinitionPersistenceHelper.persistXML(this, stream); + } catch (IOException e) { + abort(Messages.TargetDefinition_3, e); + } catch (ParserConfigurationException e) { + abort(Messages.TargetDefinition_3, e); + } catch (TransformerException e) { + abort(Messages.TargetDefinition_3, e); + } + } + + /** + * Throws a core exception with the given message and underlying exception (possibly + * null). + * + * @param message message + * @param e underlying cause of the exception or null + * @throws CoreException + */ + private void abort(String message, Exception e) throws CoreException { + throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, message, e)); + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#getImplicitDependencies() + */ + public BundleInfo[] getImplicitDependencies() { + return fImplicit; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#resolveImplicitDependencies(org.eclipse.core.runtime.IProgressMonitor) + */ + public BundleInfo[] resolveImplicitDependencies(IProgressMonitor monitor) throws CoreException { + int size = 0; + if (fImplicit != null) { + size = fImplicit.length; + } + if (size == 0) { + return new BundleInfo[0]; + } + return AbstractBundleContainer.getMatchingBundles(resolveBundles(null), fImplicit); + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setImplicitDependencies(org.eclipse.equinox.internal.provisional.frameworkadmin.BundleInfo[]) + */ + public void setImplicitDependencies(BundleInfo[] bundles) { + if (bundles != null && bundles.length == 0) { + bundles = null; + } + fImplicit = bundles; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#getJREContainer() + */ + public IPath getJREContainer() { + return fJREContainer; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setJREContainer(org.eclipse.core.runtime.IPath) + */ + public void setJREContainer(IPath containerPath) { + fJREContainer = containerPath; + } + + /** + * Returns whether the content of this definition is equal to the content of the specified definition. + * + * @param definition + * @return whether the content of this definition is equal to the content of the specified definition + */ + public boolean isContentEqual(ITargetDefinition definition) { + if (isNullOrEqual(getName(), definition.getName()) && isNullOrEqual(getDescription(), definition.getDescription()) && isNullOrEqual(getArch(), definition.getArch()) && isNullOrEqual(getNL(), definition.getNL()) && isNullOrEqual(getOS(), definition.getOS()) && isNullOrEqual(getWS(), definition.getWS()) && isNullOrEqual(getProgramArguments(), definition.getProgramArguments()) && isNullOrEqual(getVMArguments(), definition.getVMArguments())) { + // check containers and implicit dependencies + IBundleContainer[] c1 = getBundleContainers(); + IBundleContainer[] c2 = definition.getBundleContainers(); + if (areContainersEqual(c1, c2)) { + return areEqual(getImplicitDependencies(), definition.getImplicitDependencies()); + } + } + return false; + } + + private boolean areEqual(BundleInfo[] c1, BundleInfo[] c2) { + if (c1 == null) { + return c2 == null; + } + if (c2 == null) { + return false; + } + if (c1.length == c2.length) { + for (int i = 0; i < c2.length; i++) { + if (!c1[i].equals(c2[i])) { + return false; + } + } + return true; + } + return false; + } + + private boolean isNullOrEqual(Object o1, Object o2) { + if (o1 == null) { + return o2 == null; + } + if (o2 == null) { + return false; + } + return o1.equals(o2); + } + + private boolean areContainersEqual(IBundleContainer[] c1, IBundleContainer[] c2) { + if (c1 == null) { + return c2 == null; + } + if (c2 == null) { + return false; + } + if (c1.length == c2.length) { + for (int i = 0; i < c2.length; i++) { + AbstractBundleContainer ac1 = (AbstractBundleContainer) c1[i]; + AbstractBundleContainer ac2 = (AbstractBundleContainer) c2[i]; + if (!ac1.isContentEqual(ac2)) { + return false; + } + } + return true; + } + return false; + } +} Index: src/org/eclipse/pde/internal/core/target/impl/FeatureBundleContainer.java =================================================================== RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/impl/FeatureBundleContainer.java,v retrieving revision 1.5 diff -u -r1.5 FeatureBundleContainer.java --- src/org/eclipse/pde/internal/core/target/impl/FeatureBundleContainer.java 21 Jan 2009 20:40:14 -0000 1.5 +++ src/org/eclipse/pde/internal/core/target/impl/FeatureBundleContainer.java 22 Jan 2009 22:27:45 -0000 @@ -1,206 +1,226 @@ -/******************************************************************************* - * Copyright (c) 2009 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.target.impl; - -import java.io.File; -import java.util.*; -import org.eclipse.core.runtime.*; -import org.eclipse.equinox.internal.provisional.frameworkadmin.BundleInfo; -import org.eclipse.osgi.util.NLS; -import org.eclipse.pde.internal.core.ExternalFeatureModelManager; -import org.eclipse.pde.internal.core.PDECore; -import org.eclipse.pde.internal.core.ifeature.*; -import org.eclipse.pde.internal.core.target.provisional.IBundleContainer; -import org.eclipse.pde.internal.core.target.provisional.ITargetPlatformService; - -/** - * A container of the bundles contained in a feature. - * - * @since 3.5 - */ -public class FeatureBundleContainer extends AbstractBundleContainer { - - /** - * Constant describing the type of bundle container - */ - public static final String TYPE = "Feature"; //$NON-NLS-1$ - - /** - * Feature symbolic name - */ - private String fId; - - /** - * Feature version or null - */ - private String fVersion; - - /** - * Install location which may contain string substitution variables - */ - private String fHome; - - /** - * Constructs a new feature bundle container for the feature at the specified - * location. Plug-ins are resolved in the plug-ins directory of the given home - * directory. When version is unspecified, the most recent version is used. - * - * @param home root directory containing the features directory which - * may contain string substitution variables - * @param name feature symbolic name - * @param version feature version, or null if unspecified - */ - FeatureBundleContainer(String home, String name, String version) { - fId = name; - fVersion = version; - fHome = home; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#getLocation(boolean) - */ - public String getLocation(boolean resolve) throws CoreException { - if (resolve) { - return resolveHomeLocation().toOSString(); - } - return fHome; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#getType() - */ - public String getType() { - return TYPE; - } - - /** - * Returns the symbolic name of the feature this bundle container resolves from - * - * @return string feature id (symbolic name) - */ - public String getFeatureId() { - return fId; - } - - /** - * Returns the version of the feature this bundle container resolves from if - * a version was specified. - * - * @return string feature version or null - */ - public String getFeatureVersion() { - return fVersion; - } - - /** - * Returns the home location with all variables resolved as a path. - * - * @return resolved home location - * @throws CoreException - */ - private IPath resolveHomeLocation() throws CoreException { - return new Path(resolveVariables(fHome)); - } - - /** - * Resolves and returns the directory containing the feature. - * - * @return feature directory - * @throws CoreException if unable to resolve - */ - private File resolveFeatureLocation() throws CoreException { - File features = resolveHomeLocation().append("features").toFile(); //$NON-NLS-1$ - if (!features.exists() || features.isFile()) { - throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.FeatureBundleContainer_0, features.toString()))); - } - // if a specific version is specified, use it - if (fVersion != null) { - StringBuffer buf = new StringBuffer(); - String name = buf.append(fId).append("_").append(fVersion).toString(); //$NON-NLS-1$ - return new File(features, name); - } - // use most recent version - String[] list = features.list(); - List versions = new ArrayList(); - StringBuffer buf = new StringBuffer(); - String prefix = buf.append(fId).append("_").toString(); //$NON-NLS-1$ - for (int i = 0; i < list.length; i++) { - String name = list[i]; - if (name.startsWith(prefix)) { - versions.add(name); - } - } - if (versions.isEmpty()) { - throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.FeatureBundleContainer_1, fId))); - } - Collections.sort(versions); - String name = (String) versions.get(versions.size() - 1); - return new File(features, name); - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#resolveAllBundles(org.eclipse.core.runtime.IProgressMonitor) - */ - protected BundleInfo[] resolveAllBundles(IProgressMonitor monitor) throws CoreException { - return resolveBundles0(monitor, false); - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#resolveAllSourceBundles(org.eclipse.core.runtime.IProgressMonitor) - */ - protected BundleInfo[] resolveAllSourceBundles(IProgressMonitor monitor) throws CoreException { - return resolveBundles0(monitor, true); - } - - private BundleInfo[] resolveBundles0(IProgressMonitor monitor, boolean source) throws CoreException { - IFeatureModel model = null; - try { - File location = resolveFeatureLocation(); - File manifest = new File(location, "feature.xml"); //$NON-NLS-1$ - if (!manifest.exists() || !manifest.isFile()) { - throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.FeatureBundleContainer_2, fId))); - } - model = ExternalFeatureModelManager.createModel(manifest); - if (model == null || !model.isLoaded()) { - throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.FeatureBundleContainer_2, fId))); - } - // search bundles in plug-ins directory - ITargetPlatformService service = (ITargetPlatformService) PDECore.getDefault().acquireService(ITargetPlatformService.class.getName()); - if (service == null) { - throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, Messages.FeatureBundleContainer_4)); - } - File dir = new File(manifest.getParentFile().getParentFile().getParentFile(), "plugins"); //$NON-NLS-1$ - if (!dir.exists() || !dir.isDirectory()) { - throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.FeatureBundleContainer_5, fId))); - } - IBundleContainer container = service.newDirectoryContainer(dir.getAbsolutePath()); - BundleInfo[] bundles = null; - if (source) { - bundles = container.resolveSourceBundles(null); - } else { - bundles = container.resolveBundles(null); - } - IFeature feature = model.getFeature(); - IFeaturePlugin[] plugins = feature.getPlugins(); - BundleInfo[] matchInfos = new BundleInfo[plugins.length]; - for (int i = 0; i < plugins.length; i++) { - IFeaturePlugin plugin = plugins[i]; - matchInfos[i] = new BundleInfo(plugin.getId(), plugin.getVersion(), null, BundleInfo.NO_LEVEL, false); - } - return AbstractBundleContainer.getMatchingBundles(bundles, matchInfos); - } finally { - if (model != null) { - model.dispose(); - } - } - } - -} +/******************************************************************************* + * Copyright (c) 2009 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.target.impl; + +import java.io.File; +import java.util.*; +import org.eclipse.core.runtime.*; +import org.eclipse.equinox.internal.provisional.frameworkadmin.BundleInfo; +import org.eclipse.osgi.util.NLS; +import org.eclipse.pde.internal.core.ExternalFeatureModelManager; +import org.eclipse.pde.internal.core.PDECore; +import org.eclipse.pde.internal.core.ifeature.*; +import org.eclipse.pde.internal.core.target.provisional.IBundleContainer; +import org.eclipse.pde.internal.core.target.provisional.ITargetPlatformService; + +/** + * A container of the bundles contained in a feature. + * + * @since 3.5 + */ +public class FeatureBundleContainer extends AbstractBundleContainer { + + /** + * Constant describing the type of bundle container + */ + public static final String TYPE = "Feature"; //$NON-NLS-1$ + + /** + * Feature symbolic name + */ + private String fId; + + /** + * Feature version or null + */ + private String fVersion; + + /** + * Install location which may contain string substitution variables + */ + private String fHome; + + /** + * Constructs a new feature bundle container for the feature at the specified + * location. Plug-ins are resolved in the plug-ins directory of the given home + * directory. When version is unspecified, the most recent version is used. + * + * @param home root directory containing the features directory which + * may contain string substitution variables + * @param name feature symbolic name + * @param version feature version, or null if unspecified + */ + FeatureBundleContainer(String home, String name, String version) { + fId = name; + fVersion = version; + fHome = home; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#getLocation(boolean) + */ + public String getLocation(boolean resolve) throws CoreException { + if (resolve) { + return resolveHomeLocation().toOSString(); + } + return fHome; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#getType() + */ + public String getType() { + return TYPE; + } + + /** + * Returns the symbolic name of the feature this bundle container resolves from + * + * @return string feature id (symbolic name) + */ + public String getFeatureId() { + return fId; + } + + /** + * Returns the version of the feature this bundle container resolves from if + * a version was specified. + * + * @return string feature version or null + */ + public String getFeatureVersion() { + return fVersion; + } + + /** + * Returns the home location with all variables resolved as a path. + * + * @return resolved home location + * @throws CoreException + */ + private IPath resolveHomeLocation() throws CoreException { + return new Path(resolveVariables(fHome)); + } + + /** + * Resolves and returns the directory containing the feature. + * + * @return feature directory + * @throws CoreException if unable to resolve + */ + private File resolveFeatureLocation() throws CoreException { + File features = resolveHomeLocation().append("features").toFile(); //$NON-NLS-1$ + if (!features.exists() || features.isFile()) { + throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.FeatureBundleContainer_0, features.toString()))); + } + // if a specific version is specified, use it + if (fVersion != null) { + StringBuffer buf = new StringBuffer(); + String name = buf.append(fId).append("_").append(fVersion).toString(); //$NON-NLS-1$ + return new File(features, name); + } + // use most recent version + String[] list = features.list(); + List versions = new ArrayList(); + StringBuffer buf = new StringBuffer(); + String prefix = buf.append(fId).append("_").toString(); //$NON-NLS-1$ + for (int i = 0; i < list.length; i++) { + String name = list[i]; + if (name.startsWith(prefix)) { + versions.add(name); + } + } + if (versions.isEmpty()) { + throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.FeatureBundleContainer_1, fId))); + } + Collections.sort(versions); + String name = (String) versions.get(versions.size() - 1); + return new File(features, name); + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#resolveAllBundles(org.eclipse.core.runtime.IProgressMonitor) + */ + protected BundleInfo[] resolveAllBundles(IProgressMonitor monitor) throws CoreException { + return resolveBundles0(monitor, false); + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#resolveAllSourceBundles(org.eclipse.core.runtime.IProgressMonitor) + */ + protected BundleInfo[] resolveAllSourceBundles(IProgressMonitor monitor) throws CoreException { + return resolveBundles0(monitor, true); + } + + private BundleInfo[] resolveBundles0(IProgressMonitor monitor, boolean source) throws CoreException { + IFeatureModel model = null; + try { + File location = resolveFeatureLocation(); + File manifest = new File(location, "feature.xml"); //$NON-NLS-1$ + if (!manifest.exists() || !manifest.isFile()) { + throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.FeatureBundleContainer_2, fId))); + } + model = ExternalFeatureModelManager.createModel(manifest); + if (model == null || !model.isLoaded()) { + throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.FeatureBundleContainer_2, fId))); + } + // search bundles in plug-ins directory + ITargetPlatformService service = (ITargetPlatformService) PDECore.getDefault().acquireService(ITargetPlatformService.class.getName()); + if (service == null) { + throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, Messages.FeatureBundleContainer_4)); + } + File dir = new File(manifest.getParentFile().getParentFile().getParentFile(), "plugins"); //$NON-NLS-1$ + if (!dir.exists() || !dir.isDirectory()) { + throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.FeatureBundleContainer_5, fId))); + } + IBundleContainer container = service.newDirectoryContainer(dir.getAbsolutePath()); + BundleInfo[] bundles = null; + if (source) { + bundles = container.resolveSourceBundles(null); + } else { + bundles = container.resolveBundles(null); + } + IFeature feature = model.getFeature(); + IFeaturePlugin[] plugins = feature.getPlugins(); + BundleInfo[] matchInfos = new BundleInfo[plugins.length]; + for (int i = 0; i < plugins.length; i++) { + IFeaturePlugin plugin = plugins[i]; + matchInfos[i] = new BundleInfo(plugin.getId(), plugin.getVersion(), null, BundleInfo.NO_LEVEL, false); + } + return AbstractBundleContainer.getMatchingBundles(bundles, matchInfos); + } finally { + if (model != null) { + model.dispose(); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer#isContentEqual(org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer) + */ + public boolean isContentEqual(AbstractBundleContainer container) { + if (container instanceof FeatureBundleContainer) { + FeatureBundleContainer fbc = (FeatureBundleContainer) container; + return fHome.equals(fbc.fHome) && fId.equals(fbc.fId) && isNullOrEqual(fVersion, fVersion) && super.isContentEqual(container); + } + return false; + } + + private boolean isNullOrEqual(Object o1, Object o2) { + if (o1 == null) { + return o2 == null; + } + if (o2 == null) { + return false; + } + return o1.equals(o2); + } +} Index: src/org/eclipse/pde/internal/core/target/impl/AbstractBundleContainer.java =================================================================== RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/impl/AbstractBundleContainer.java,v retrieving revision 1.6 diff -u -r1.6 AbstractBundleContainer.java --- src/org/eclipse/pde/internal/core/target/impl/AbstractBundleContainer.java 21 Jan 2009 20:40:14 -0000 1.6 +++ src/org/eclipse/pde/internal/core/target/impl/AbstractBundleContainer.java 22 Jan 2009 22:27:45 -0000 @@ -1,183 +1,207 @@ -/******************************************************************************* - * Copyright (c) 2009 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.target.impl; - -import java.util.*; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.variables.IStringVariableManager; -import org.eclipse.core.variables.VariablesPlugin; -import org.eclipse.equinox.internal.provisional.frameworkadmin.BundleInfo; -import org.eclipse.pde.internal.core.target.provisional.IBundleContainer; - -/** - * Common function for bundle containers. - * - * @since 3.5 - */ -public abstract class AbstractBundleContainer implements IBundleContainer { - - /** - * Bundle restrictions (subset) this container is restricted to or null if - * no restrictions. - */ - private BundleInfo[] fRestrictions; - - /** - * Resolves any string substitution variables in the given text returning - * the result. - * - * @param text text to resolve - * @return result of the resolution - * @throws CoreException if unable to resolve - */ - protected String resolveVariables(String text) throws CoreException { - IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager(); - return manager.performStringSubstitution(text); - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.IBundleContainer#resolveBundles(org.eclipse.core.runtime.IProgressMonitor) - */ - public final BundleInfo[] resolveBundles(IProgressMonitor monitor) throws CoreException { - BundleInfo[] all = resolveAllBundles(monitor); - return getMatchingBundles(all, getRestrictions()); - } - - /** - * Resolves all executable bundles in this container regardless of any bundle restrictions. - *

- * Subclasses must implement this method. - *

- * @param monitor progress monitor - * @return all executable bundles in this container regardless of any bundle restrictions - * @throws CoreException if an error occurs - */ - protected abstract BundleInfo[] resolveAllBundles(IProgressMonitor monitor) throws CoreException; - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.IBundleContainer#resolveSourceBundles(org.eclipse.core.runtime.IProgressMonitor) - */ - public final BundleInfo[] resolveSourceBundles(IProgressMonitor monitor) throws CoreException { - BundleInfo[] all = resolveAllSourceBundles(monitor); - return getMatchingBundles(all, getRestrictions()); - } - - /** - * Resolves all source bundles in this container regardless of any bundle restrictions. - *

- * Subclasses must implement this method. - *

- * @param monitor progress monitor - * @return all source bundles in this container regardless of any bundle restrictions - * @throws CoreException if an error occurs - */ - protected abstract BundleInfo[] resolveAllSourceBundles(IProgressMonitor monitor) throws CoreException; - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.IBundleContainer#getRestrictions() - */ - public BundleInfo[] getRestrictions() { - return fRestrictions; - } - - /* (non-Javadoc) - * @see org.eclipse.pde.internal.core.target.provisional.IBundleContainer#setRestrictions(org.eclipse.equinox.internal.provisional.frameworkadmin.BundleInfo[]) - */ - public void setRestrictions(BundleInfo[] bundles) { - fRestrictions = bundles; - } - - /** - * Returns bundles from the specified collection that match the symbolic names - * and/or version in the specified criteria. When no version is specified - * the newest version (if any) is selected. - * - * @param collection bundles to resolve against match criteria - * @param criteria bundles to select or null if no restrictions - * @return bundles that match this container's restrictions - */ - static BundleInfo[] getMatchingBundles(BundleInfo[] collection, BundleInfo[] criteria) { - if (criteria == null) { - return collection; - } - // map bundles names to available versions - Map bundleMap = new HashMap(collection.length); - for (int i = 0; i < collection.length; i++) { - BundleInfo info = collection[i]; - List list = (List) bundleMap.get(info.getSymbolicName()); - if (list == null) { - list = new ArrayList(3); - bundleMap.put(info.getSymbolicName(), list); - } - list.add(info); - } - List subset = new ArrayList(criteria.length); - for (int i = 0; i < criteria.length; i++) { - BundleInfo info = criteria[i]; - List list = (List) bundleMap.get(info.getSymbolicName()); - if (list != null) { - String version = info.getVersion(); - if (version == null) { - // select newest - if (list.size() > 1) { - // sort the list - Collections.sort(list, new Comparator() { - public int compare(Object o1, Object o2) { - return ((BundleInfo) o1).getVersion().compareTo(((BundleInfo) o2).getVersion()); - } - }); - } - // select the last one - subset.add(list.get(list.size() - 1)); - } else { - Iterator iterator = list.iterator(); - boolean found = false; - while (iterator.hasNext() && !found) { - BundleInfo bundle = (BundleInfo) iterator.next(); - if (bundle.getVersion().equals(version)) { - subset.add(bundle); - found = true; - } - } - if (!found) { - // TODO: report not found? exception? - } - } - } else { - // TODO: report not found? exception? - } - } - return (BundleInfo[]) subset.toArray(new BundleInfo[subset.size()]); - } - - /** - * Returns a string that identifies the type of bundle container. This type is persisted to xml - * so that the correct bundle container is created when deserializing the xml. This type is also - * used to alter how the containers are presented to the user in the UI. - * - * @return string identifier for the type of bundle container. - */ - public abstract String getType(); - - /** - * Returns a path in the local file system to the root of the bundle container. - *

- * TODO: Ideally we won't need this method. Currently the PDE target platform preferences are - * based on a home location and additional locations, so we need the information. - *

- * @param resolve whether to resolve variables in the path - * @return home location - * @exception CoreException if unable to resolve the location - */ - public abstract String getLocation(boolean resolve) throws CoreException; - -} +/******************************************************************************* + * Copyright (c) 2009 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.target.impl; + +import java.util.*; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.variables.IStringVariableManager; +import org.eclipse.core.variables.VariablesPlugin; +import org.eclipse.equinox.internal.provisional.frameworkadmin.BundleInfo; +import org.eclipse.pde.internal.core.target.provisional.IBundleContainer; + +/** + * Common function for bundle containers. + * + * @since 3.5 + */ +public abstract class AbstractBundleContainer implements IBundleContainer { + + /** + * Bundle restrictions (subset) this container is restricted to or null if + * no restrictions. + */ + private BundleInfo[] fRestrictions; + + /** + * Resolves any string substitution variables in the given text returning + * the result. + * + * @param text text to resolve + * @return result of the resolution + * @throws CoreException if unable to resolve + */ + protected String resolveVariables(String text) throws CoreException { + IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager(); + return manager.performStringSubstitution(text); + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.IBundleContainer#resolveBundles(org.eclipse.core.runtime.IProgressMonitor) + */ + public final BundleInfo[] resolveBundles(IProgressMonitor monitor) throws CoreException { + BundleInfo[] all = resolveAllBundles(monitor); + return getMatchingBundles(all, getRestrictions()); + } + + /** + * Resolves all executable bundles in this container regardless of any bundle restrictions. + *

+ * Subclasses must implement this method. + *

+ * @param monitor progress monitor + * @return all executable bundles in this container regardless of any bundle restrictions + * @throws CoreException if an error occurs + */ + protected abstract BundleInfo[] resolveAllBundles(IProgressMonitor monitor) throws CoreException; + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.IBundleContainer#resolveSourceBundles(org.eclipse.core.runtime.IProgressMonitor) + */ + public final BundleInfo[] resolveSourceBundles(IProgressMonitor monitor) throws CoreException { + BundleInfo[] all = resolveAllSourceBundles(monitor); + return getMatchingBundles(all, getRestrictions()); + } + + /** + * Resolves all source bundles in this container regardless of any bundle restrictions. + *

+ * Subclasses must implement this method. + *

+ * @param monitor progress monitor + * @return all source bundles in this container regardless of any bundle restrictions + * @throws CoreException if an error occurs + */ + protected abstract BundleInfo[] resolveAllSourceBundles(IProgressMonitor monitor) throws CoreException; + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.IBundleContainer#getRestrictions() + */ + public BundleInfo[] getRestrictions() { + return fRestrictions; + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.core.target.provisional.IBundleContainer#setRestrictions(org.eclipse.equinox.internal.provisional.frameworkadmin.BundleInfo[]) + */ + public void setRestrictions(BundleInfo[] bundles) { + fRestrictions = bundles; + } + + /** + * Returns bundles from the specified collection that match the symbolic names + * and/or version in the specified criteria. When no version is specified + * the newest version (if any) is selected. + * + * @param collection bundles to resolve against match criteria + * @param criteria bundles to select or null if no restrictions + * @return bundles that match this container's restrictions + */ + static BundleInfo[] getMatchingBundles(BundleInfo[] collection, BundleInfo[] criteria) { + if (criteria == null) { + return collection; + } + // map bundles names to available versions + Map bundleMap = new HashMap(collection.length); + for (int i = 0; i < collection.length; i++) { + BundleInfo info = collection[i]; + List list = (List) bundleMap.get(info.getSymbolicName()); + if (list == null) { + list = new ArrayList(3); + bundleMap.put(info.getSymbolicName(), list); + } + list.add(info); + } + List subset = new ArrayList(criteria.length); + for (int i = 0; i < criteria.length; i++) { + BundleInfo info = criteria[i]; + List list = (List) bundleMap.get(info.getSymbolicName()); + if (list != null) { + String version = info.getVersion(); + if (version == null) { + // select newest + if (list.size() > 1) { + // sort the list + Collections.sort(list, new Comparator() { + public int compare(Object o1, Object o2) { + return ((BundleInfo) o1).getVersion().compareTo(((BundleInfo) o2).getVersion()); + } + }); + } + // select the last one + subset.add(list.get(list.size() - 1)); + } else { + Iterator iterator = list.iterator(); + boolean found = false; + while (iterator.hasNext() && !found) { + BundleInfo bundle = (BundleInfo) iterator.next(); + if (bundle.getVersion().equals(version)) { + subset.add(bundle); + found = true; + } + } + if (!found) { + // TODO: report not found? exception? + } + } + } else { + // TODO: report not found? exception? + } + } + return (BundleInfo[]) subset.toArray(new BundleInfo[subset.size()]); + } + + /** + * Returns a string that identifies the type of bundle container. This type is persisted to xml + * so that the correct bundle container is created when deserializing the xml. This type is also + * used to alter how the containers are presented to the user in the UI. + * + * @return string identifier for the type of bundle container. + */ + public abstract String getType(); + + /** + * Returns a path in the local file system to the root of the bundle container. + *

+ * TODO: Ideally we won't need this method. Currently the PDE target platform preferences are + * based on a home location and additional locations, so we need the information. + *

+ * @param resolve whether to resolve variables in the path + * @return home location + * @exception CoreException if unable to resolve the location + */ + public abstract String getLocation(boolean resolve) throws CoreException; + + /** + * Returns whether restrictions are equivalent. Subclasses should override for other data. + * + * @param container bundle container + * @return whether content is equivalent + */ + public boolean isContentEqual(AbstractBundleContainer container) { + if (fRestrictions == null) { + return container.fRestrictions == null; + } + if (container.fRestrictions == null) { + return false; + } + if (fRestrictions.length == container.fRestrictions.length) { + for (int i = 0; i < fRestrictions.length; i++) { + if (!fRestrictions[i].equals(container.fRestrictions[i])) { + return false; + } + } + return true; + } + return false; + } + +} Index: src/org/eclipse/pde/internal/core/PluginModelManager.java =================================================================== RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/PluginModelManager.java,v retrieving revision 1.123 diff -u -r1.123 PluginModelManager.java --- src/org/eclipse/pde/internal/core/PluginModelManager.java 13 Oct 2008 19:21:11 -0000 1.123 +++ src/org/eclipse/pde/internal/core/PluginModelManager.java 22 Jan 2009 22:27:45 -0000 @@ -11,17 +11,20 @@ *******************************************************************************/ package org.eclipse.pde.internal.core; +import java.net.URL; import java.util.*; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.*; import org.eclipse.jdt.core.*; +import org.eclipse.osgi.service.datalocation.Location; import org.eclipse.osgi.service.resolver.*; import org.eclipse.pde.core.*; import org.eclipse.pde.core.build.IBuild; import org.eclipse.pde.core.build.IBuildEntry; import org.eclipse.pde.core.plugin.*; +import org.eclipse.pde.internal.core.target.impl.LocalTargetHandle; +import org.eclipse.pde.internal.core.target.provisional.*; public class PluginModelManager implements IModelProviderListener { @@ -369,6 +372,9 @@ if (fEntries != null) return; + // Create default target platform definition if required + initDefaultTargetPlatformDefinition(); + // Cannot assign to fEntries here - will create a race condition with isInitialized() Map entries = Collections.synchronizedMap(new TreeMap()); @@ -423,6 +429,62 @@ } /** + * Creates initial target platform definition in local metadata if not already created. + */ + private synchronized void initDefaultTargetPlatformDefinition() { + ITargetPlatformService service = (ITargetPlatformService) PDECore.getDefault().acquireService(ITargetPlatformService.class.getName()); + if (service != null) { + String memento = PDECore.getDefault().getPluginPreferences().getString(ICoreConstants.WORKSPACE_TARGET_HANDLE); + if (memento.equals("")) { //$NON-NLS-1$ + // no workspace target handle set, check for local targets + ITargetHandle[] targets = service.getTargets(null); + boolean local = false; + for (int i = 0; i < targets.length; i++) { + if (targets[i] instanceof LocalTargetHandle) { + local = true; + break; + } + } + if (!local) { + // no local targets, no workspace preference > create default target platform + ITargetDefinition target = service.newTarget(); + target.setName("Running Platform (Default)"); + Location configArea = Platform.getConfigurationLocation(); + String configLocation = null; + if (configArea != null) { + configLocation = configArea.getURL().getFile(); + } + if (configLocation != null) { + Location location = Platform.getInstallLocation(); + if (location != null) { + URL url = location.getURL(); + if (url != null) { + IPath installPath = new Path(url.getFile()); + IPath configPath = new Path(configLocation); + if (installPath.isPrefixOf(configPath)) { + // if it is the default configuration area, do not specify explicitly + configPath = configPath.removeFirstSegments(installPath.segmentCount()); + configPath = configPath.setDevice(null); + if (configPath.segmentCount() == 1 && configPath.lastSegment().equals("configuration")) { //$NON-NLS-1$ + configLocation = null; + } + } + } + } + } + IBundleContainer container = service.newProfileContainer("${eclipse_home}", configLocation); //$NON-NLS-1$ + target.setBundleContainers(new IBundleContainer[] {container}); + try { + service.saveTargetDefinition(target); + } catch (CoreException e) { + PDECore.log(e); + } + } + } + } + } + + /** * Adds the given models to the corresponding ModelEntry in the master table * * @param models the models to be added to the master tabl #P org.eclipse.pde.ui Index: plugin.properties =================================================================== RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.ui/plugin.properties,v retrieving revision 1.218 diff -u -r1.218 plugin.properties --- plugin.properties 15 Dec 2008 02:19:31 -0000 1.218 +++ plugin.properties 22 Jan 2009 22:27:47 -0000 @@ -39,6 +39,7 @@ preferences.main.name= Plug-in Development preferences.target.name = Target Platform +preferences.target.name2 = Target Platform (Experimental) preferences.compilers.name = Compilers preferences.editor.name = Editors Index: plugin.xml =================================================================== RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.ui/plugin.xml,v retrieving revision 1.452 diff -u -r1.452 plugin.xml --- plugin.xml 19 Jan 2009 21:26:17 -0000 1.452 +++ plugin.xml 22 Jan 2009 22:27:47 -0000 @@ -65,6 +65,18 @@ id="org.eclipse.pde.ui.OSGiFrameworksPreferencePage"> + + + + + + @@ -344,7 +356,7 @@ default="true" name="%editor.profile.name" icon="$nl$/icons/obj16/target_profile_xml_obj.gif" - class="org.eclipse.pde.internal.ui.editor.target.TargetEditor" + class="org.eclipse.pde.internal.ui.editor.targetdefinition.TargetEditor" contributorClass="org.eclipse.pde.internal.ui.editor.target.TargetEditorContributor" id="org.eclipse.pde.ui.targetEditor"> Index: src/org/eclipse/pde/internal/ui/shared/target/BundleContainerTable.java =================================================================== RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/shared/target/BundleContainerTable.java,v retrieving revision 1.2 diff -u -r1.2 BundleContainerTable.java --- src/org/eclipse/pde/internal/ui/shared/target/BundleContainerTable.java 22 Jan 2009 21:45:18 -0000 1.2 +++ src/org/eclipse/pde/internal/ui/shared/target/BundleContainerTable.java 22 Jan 2009 22:27:47 -0000 @@ -128,7 +128,7 @@ private void createDialogContents(Composite parent) { Composite comp = SWTFactory.createComposite(parent, 2, 1, GridData.FILL_BOTH); - Tree atree = new Tree(comp, SWT.V_SCROLL | SWT.H_SCROLL); + Tree atree = new Tree(comp, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER); atree.setLayout(new GridLayout()); GridData gd = new GridData(GridData.FILL_BOTH); atree.setLayoutData(gd); Index: src/org/eclipse/pde/internal/ui/wizards/target/EditTargetNode.java =================================================================== RCS file: src/org/eclipse/pde/internal/ui/wizards/target/EditTargetNode.java diff -N src/org/eclipse/pde/internal/ui/wizards/target/EditTargetNode.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/pde/internal/ui/wizards/target/EditTargetNode.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2009 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.ui.wizards.target; + +import org.eclipse.jface.wizard.IWizard; +import org.eclipse.jface.wizard.IWizardNode; +import org.eclipse.pde.internal.core.target.provisional.ITargetDefinition; +import org.eclipse.swt.graphics.Point; + +/** + * Embedded wizard to edit a target + */ +public class EditTargetNode implements IWizardNode { + + private EditTargetDefinitionWizard fWizard; + private ITargetDefinition fDefinition; + + /* (non-Javadoc) + * @see org.eclipse.jface.wizard.IWizardNode#dispose() + */ + public void dispose() { + if (fWizard != null) { + fWizard.dispose(); + fWizard = null; + fDefinition = null; + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.wizard.IWizardNode#getExtent() + */ + public Point getExtent() { + return new Point(-1, -1); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.wizard.IWizardNode#getWizard() + */ + public IWizard getWizard() { + if (fWizard == null) { + fWizard = new EditTargetDefinitionWizard(fDefinition); + fWizard.setWindowTitle("New Target Definition"); + } + return fWizard; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.wizard.IWizardNode#isContentCreated() + */ + public boolean isContentCreated() { + return fWizard != null; + } + + /** + * Sets the target being edited. + * + * @param definition + */ + public void setTargetDefinition(ITargetDefinition definition) { + fDefinition = definition; + if (fWizard != null) { + fWizard.setTargetDefinition(definition); + } + } + +} Index: src/org/eclipse/pde/internal/ui/wizards/target/TargetCreationPage.java =================================================================== RCS file: src/org/eclipse/pde/internal/ui/wizards/target/TargetCreationPage.java diff -N src/org/eclipse/pde/internal/ui/wizards/target/TargetCreationPage.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/pde/internal/ui/wizards/target/TargetCreationPage.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,277 @@ +/******************************************************************************* + * Copyright (c) 2005, 2009 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.ui.wizards.target; + +import java.io.*; +import java.net.URL; +import javax.xml.parsers.ParserConfigurationException; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.wizard.IWizardPage; +import org.eclipse.jface.wizard.WizardSelectionPage; +import org.eclipse.pde.internal.core.PDECore; +import org.eclipse.pde.internal.core.TargetDefinitionManager; +import org.eclipse.pde.internal.core.itarget.ITargetModel; +import org.eclipse.pde.internal.core.target.TargetModel; +import org.eclipse.pde.internal.core.target.impl.TargetDefinitionPersistenceHelper; +import org.eclipse.pde.internal.core.target.provisional.*; +import org.eclipse.pde.internal.ui.PDEUIMessages; +import org.eclipse.pde.internal.ui.editor.target.OpenTargetProfileAction; +import org.eclipse.pde.internal.ui.util.SWTUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.*; +import org.xml.sax.SAXException; + +/** + * First wizard page used to create a target definition. Defines the location where + * the definition will be created and how to seed the definition. + */ +public class TargetCreationPage extends WizardSelectionPage { + + protected static final int USE_DEFAULT = 0; + protected static final int USE_CURRENT_TP = 1; + protected static final int USE_EXISTING_TARGET = 2; + + private Button fDefaultButton; + private Button fCurrentTPButton; + private Button fExistingTargetButton; + private Combo fTargets; + private String[] fTargetIds; + private Button fPreviewButton; + + public TargetCreationPage(String pageName) { + super(pageName); + setTitle(PDEUIMessages.TargetProfileWizardPage_title); + setDescription(PDEUIMessages.TargetProfileWizardPage_description); + } + + /** + * Returns the target service or null if none. + * + * @return target service or null + */ + protected ITargetPlatformService getTargetService() { + return (ITargetPlatformService) PDECore.getDefault().acquireService(ITargetPlatformService.class.getName()); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite parent) { + Group group = new Group(parent, SWT.NONE); + group.setText("Initialize target with:"); + group.setLayout(new GridLayout(3, false)); + group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + fDefaultButton = new Button(group, SWT.RADIO); + fDefaultButton.setText("&Default settings - the running platform"); + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalSpan = 3; + fDefaultButton.setLayoutData(gd); + fDefaultButton.setSelection(true); + fDefaultButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + + } + }); + + fCurrentTPButton = new Button(group, SWT.RADIO); + fCurrentTPButton.setText("C&urrent target platform settings"); + gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalSpan = 3; + fCurrentTPButton.setLayoutData(gd); + fCurrentTPButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + + } + }); + + fExistingTargetButton = new Button(group, SWT.RADIO); + fExistingTargetButton.setText("&Template settings:"); + fExistingTargetButton.setLayoutData(new GridData()); + fExistingTargetButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + boolean enabled = fExistingTargetButton.getSelection(); + fTargets.setEnabled(enabled); + fPreviewButton.setEnabled(enabled); + } + }); + fExistingTargetButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + + } + }); + + fTargets = new Combo(group, SWT.SINGLE | SWT.READ_ONLY); + fTargets.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + fTargets.setEnabled(false); + initializeTargetCombo(); + + fPreviewButton = new Button(group, SWT.PUSH); + fPreviewButton.setText(PDEUIMessages.TargetProfileWizardPage_viewProfile); + fPreviewButton.setLayoutData(new GridData()); + SWTUtil.setButtonDimensionHint(fPreviewButton); + fPreviewButton.setEnabled(false); + fPreviewButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + InputStream stream = null; + try { + URL url = getExternalTargetURL(); + if (url != null) + stream = new BufferedInputStream(url.openStream()); + if (stream != null) { + ITargetModel model = new TargetModel(); + model.load(stream, false); + new OpenTargetProfileAction(getShell(), model, fTargets.getText()).run(); + } + } catch (IOException e1) { + } catch (CoreException e2) { + } finally { + try { + if (stream != null) + stream.close(); + } catch (IOException e3) { + } + } + } + }); + + Dialog.applyDialogFont(group); + setSelectedNode(new EditTargetNode()); + setControl(group); + setPageComplete(true); + } + + private URL getExternalTargetURL() { + TargetDefinitionManager manager = PDECore.getDefault().getTargetProfileManager(); + IConfigurationElement elem = manager.getTarget(fTargetIds[fTargets.getSelectionIndex()]); + if (elem != null) { + String path = elem.getAttribute("definition"); //$NON-NLS-1$ + String symbolicName = elem.getDeclaringExtension().getNamespaceIdentifier(); + return TargetDefinitionManager.getResourceURL(symbolicName, path); + } + return null; + } + + protected void initializeTargetCombo() { + IConfigurationElement[] elements = PDECore.getDefault().getTargetProfileManager().getSortedTargets(); + fTargetIds = new String[elements.length]; + for (int i = 0; i < elements.length; i++) { + String name = elements[i].getAttribute("name"); //$NON-NLS-1$ + if (fTargets.indexOf(name) == -1) + fTargets.add(name); + fTargetIds[i] = elements[i].getAttribute("id"); //$NON-NLS-1$ + } + if (elements.length > 0) + fTargets.select(0); + } + + protected int getInitializationOption() { + if (fDefaultButton.getSelection()) + return USE_DEFAULT; + else if (fCurrentTPButton.getSelection()) + return USE_CURRENT_TP; + return USE_EXISTING_TARGET; + } + + protected String getTargetId() { + return fTargetIds[fTargets.getSelectionIndex()]; + } + + private ITargetDefinition createTarget() { + ITargetPlatformService service = getTargetService(); + if (service != null) { + ITargetDefinition definition = service.newTarget(); + switch (getInitializationOption()) { + case USE_DEFAULT : + populateBasicTarget(definition); + break; + case USE_CURRENT_TP : + populateFromCurrentTargetPlatform(definition); + break; + case USE_EXISTING_TARGET : + try { + populateFromTemplate(definition, getTargetId()); + } catch (CoreException e) { + setErrorMessage(e.getMessage()); + return null; + } + break; + } + return definition; + } + return null; + } + + /** + * Applies basic target settings to the given target definition. + * + * @param definition + */ + private void populateBasicTarget(ITargetDefinition definition) { + ITargetPlatformService service = getTargetService(); + if (service != null) { + definition.setName("Running Platform (Default)"); + definition.setBundleContainers(new IBundleContainer[] {service.newProfileContainer("${eclipse_home}", null)}); + } + } + + /** + * Populates the given definition from current target platform settings. + * + * @param definition + */ + private void populateFromCurrentTargetPlatform(ITargetDefinition definition) { + // TODO: + } + + /** + * Populates the given definition from the specified target template. + * + * @param definition + * @param id target extension identifier + * @exception CoreException if unable to complete + */ + private void populateFromTemplate(ITargetDefinition definition, String id) throws CoreException { + IConfigurationElement elem = PDECore.getDefault().getTargetProfileManager().getTarget(id); + String path = elem.getAttribute("definition"); //$NON-NLS-1$ + String symbolicName = elem.getDeclaringExtension().getNamespaceIdentifier(); + URL url = TargetDefinitionManager.getResourceURL(symbolicName, path); + if (url != null) { + try { + TargetDefinitionPersistenceHelper.initFromXML(definition, new BufferedInputStream(url.openStream())); + } catch (IOException e) { + // TODO: throw CE + } catch (ParserConfigurationException e) { + // TODO: throw CE + } catch (SAXException e) { + // TODO: throw CE + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.wizard.WizardSelectionPage#getNextPage() + */ + public IWizardPage getNextPage() { + ITargetDefinition target = createTarget(); + if (target != null) { + ((EditTargetNode) getSelectedNode()).setTargetDefinition(target); + return super.getNextPage(); + } + return null; + } +} Index: src/org/eclipse/pde/internal/ui/wizards/target/TargetDefinitionPage.java =================================================================== RCS file: src/org/eclipse/pde/internal/ui/wizards/target/TargetDefinitionPage.java diff -N src/org/eclipse/pde/internal/ui/wizards/target/TargetDefinitionPage.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/pde/internal/ui/wizards/target/TargetDefinitionPage.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2009 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.ui.wizards.target; + +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.pde.internal.core.PDECore; +import org.eclipse.pde.internal.core.target.provisional.ITargetDefinition; +import org.eclipse.pde.internal.core.target.provisional.ITargetPlatformService; + +/** + * Common function for target definition wizard pages. + */ +public abstract class TargetDefinitionPage extends WizardPage { + + private ITargetDefinition fDefinition; + + /** + * @param pageName + */ + protected TargetDefinitionPage(String pageName, ITargetDefinition definition) { + super(pageName); + fDefinition = definition; + } + + /** + * Returns the target being edited. + * + * @return target definition or null + */ + public ITargetDefinition getTargetDefinition() { + return fDefinition; + } + + /** + * Notification the target being edited has changed to a new model. Subclasses + * should override. + */ + protected void targetChanged(ITargetDefinition definition) { + fDefinition = definition; + } + + /** + * Returns the target service or null if none. + * + * @return target service or null + */ + protected static ITargetPlatformService getTargetService() { + return (ITargetPlatformService) PDECore.getDefault().acquireService(ITargetPlatformService.class.getName()); + } +} Index: src/org/eclipse/pde/internal/ui/wizards/target/NewTargetDefinitionWizard2.java =================================================================== RCS file: src/org/eclipse/pde/internal/ui/wizards/target/NewTargetDefinitionWizard2.java diff -N src/org/eclipse/pde/internal/ui/wizards/target/NewTargetDefinitionWizard2.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/pde/internal/ui/wizards/target/NewTargetDefinitionWizard2.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2005, 2009 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.ui.wizards.target; + +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.pde.internal.core.target.provisional.ITargetDefinition; +import org.eclipse.pde.internal.ui.PDEPluginImages; +import org.eclipse.pde.internal.ui.PDEUIMessages; + +/** + * Target definition wizard used to create a new target definition from + * the new target platform preference page. + */ +public class NewTargetDefinitionWizard2 extends Wizard { + + TargetCreationPage fPage; + ITargetDefinition fDefinition; + + public NewTargetDefinitionWizard2() { + super(); + setDefaultPageImageDescriptor(PDEPluginImages.DESC_TARGET_WIZ); + setWindowTitle(PDEUIMessages.NewTargetProfileWizard_title); + } + + public void addPages() { + fPage = new TargetCreationPage("profile"); //$NON-NLS-1$ + addPage(fPage); + addPage(new TargetDefinitionContentPage(null)); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.wizard.Wizard#performFinish() + */ + public boolean performFinish() { + return true; + } + + /** + * Returns the target definition created by this wizard. + * + * @return target definition or null if none + */ + public ITargetDefinition getTargetDefinition() { + return fDefinition; + } + + /** + * Sets the target being edited. + * + * @param definition target + */ + public void setTargetDefinition(ITargetDefinition definition) { + fDefinition = definition; + } +} Index: src/org/eclipse/pde/internal/ui/preferences/TargetPlatformPreferencePage2.java =================================================================== RCS file: src/org/eclipse/pde/internal/ui/preferences/TargetPlatformPreferencePage2.java diff -N src/org/eclipse/pde/internal/ui/preferences/TargetPlatformPreferencePage2.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/pde/internal/ui/preferences/TargetPlatformPreferencePage2.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,350 @@ +/******************************************************************************* + * Copyright (c) 2009 EclipseSource 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: + * EclipseSource Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.pde.internal.ui.preferences; + +import java.util.*; +import java.util.List; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.jface.viewers.*; +import org.eclipse.jface.window.Window; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.pde.internal.core.PDECore; +import org.eclipse.pde.internal.core.target.impl.TargetDefinition; +import org.eclipse.pde.internal.core.target.provisional.*; +import org.eclipse.pde.internal.ui.*; +import org.eclipse.pde.internal.ui.wizards.target.EditTargetDefinitionWizard; +import org.eclipse.pde.internal.ui.wizards.target.NewTargetDefinitionWizard2; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.*; +import org.eclipse.ui.*; + +public class TargetPlatformPreferencePage2 extends PreferencePage implements IWorkbenchPreferencePage { + + private class TargetLabelProvider extends LabelProvider { + public Image getImage(Object element) { + return PDEPlugin.getDefault().getLabelProvider().get(PDEPluginImages.DESC_TARGET_DEFINITION); + } + + public String getText(Object element) { + String name = ((ITargetDefinition) element).getName(); + return name; + } + } + + // Table viewer + private CheckboxTableViewer fTableViewer = null; + + // Buttons + private Button fAddButton = null; + private Button fEditButton = null; + //private Button fDuplicateButton = null; + private Button fRemoveButton = null; + + // Initial collection of targets (handles are realized into definitions as working copies) + private List fTargets = new ArrayList(); + + // Removed definitions (to be removed on apply) + private List fRemoved = new ArrayList(); + + public TargetPlatformPreferencePage2() { + // nothing + } + + public void dispose() { + super.dispose(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite) + */ + public Control createContents(Composite parent) { + Composite container = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.marginHeight = layout.marginWidth = 0; + container.setLayout(layout); + + createTargetProfilesGroup(container); + + Dialog.applyDialogFont(container); + PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IHelpContextIds.TARGET_PLATFORM_PREFERENCE_PAGE); + return container; + } + + private void createTargetProfilesGroup(Composite container) { + Composite comp = SWTFactory.createComposite(container, 1, 1, GridData.FILL_BOTH, 0, 0); + SWTFactory.createWrapLabel(comp, "Add, remove or edit target definitions. Workspace plug-ins will be compiled and tested against the checked target definition.", 2, 200); + SWTFactory.createVerticalSpacer(comp, 1); + + Composite tableComposite = SWTFactory.createComposite(comp, 2, 1, GridData.FILL_BOTH, 0, 0); + SWTFactory.createWrapLabel(tableComposite, "Target Definitions: ", 2); + Table table = new Table(tableComposite, SWT.FULL_SELECTION | SWT.MULTI | SWT.BORDER | SWT.CHECK); + table.setLayoutData(new GridData(GridData.FILL_BOTH)); + fTableViewer = new CheckboxTableViewer(table); + fTableViewer.setLabelProvider(new TargetLabelProvider()); + fTableViewer.setContentProvider(ArrayContentProvider.getInstance()); + fTableViewer.addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + updateButtons(); + } + }); + fTableViewer.setComparator(new ViewerComparator()); + + // add the targets + ITargetPlatformService service = getTargetService(); + if (service != null) { + ITargetHandle[] targets = service.getTargets(null); + for (int i = 0; i < targets.length; i++) { + try { + fTargets.add(targets[i].getTargetDefinition()); + } catch (CoreException e) { + setErrorMessage(e.getMessage()); + } + } + fTableViewer.setInput(fTargets); + } + + // Single check behavior + fTableViewer.addCheckStateListener(new ICheckStateListener() { + public void checkStateChanged(CheckStateChangedEvent event) { + if (event.getChecked()) { + fTableViewer.setCheckedElements(new Object[] {event.getElement()}); + } else { + fTableViewer.setCheckedElements(new Object[0]); + } + } + }); + + Composite buttonComposite = SWTFactory.createComposite(tableComposite, 1, 1, GridData.FILL_VERTICAL | GridData.VERTICAL_ALIGN_BEGINNING, 0, 0); + fAddButton = SWTFactory.createPushButton(buttonComposite, "Add...", null); + fAddButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + NewTargetDefinitionWizard2 wizard = new NewTargetDefinitionWizard2(); + wizard.setWindowTitle("New Target Definition"); + WizardDialog dialog = new WizardDialog(fAddButton.getShell(), wizard); + if (dialog.open() == Window.OK) { + ITargetDefinition def = wizard.getTargetDefinition(); + fTargets.add(def); + fTableViewer.refresh(); + fTableViewer.setSelection(new StructuredSelection(def)); + } + } + }); + + fEditButton = SWTFactory.createPushButton(buttonComposite, "Edit...", null); + fEditButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + ITargetDefinition def = (ITargetDefinition) ((IStructuredSelection) fTableViewer.getSelection()).getFirstElement(); + EditTargetDefinitionWizard wizard = new EditTargetDefinitionWizard(def); + wizard.setWindowTitle("Edit Target Definition"); + WizardDialog dialog = new WizardDialog(fEditButton.getShell(), wizard); + if (dialog.open() == Window.OK) { + fTableViewer.refresh(); + } + } + }); + + // TODO: post M5, implement "duplicate" +// fDuplicateButton = SWTFactory.createPushButton(buttonComposite, "Duplicate...", null); +// fDuplicateButton.addSelectionListener(new SelectionAdapter() { +// public void widgetSelected(SelectionEvent e) { +// // for now we always duplicate to local metadata +// IStructuredSelection selection = (IStructuredSelection) fTableViewer.getSelection(); +// ITargetDefinition source = (ITargetDefinition) selection.getFirstElement(); +// ITargetPlatformService service = getTargetService(); +// if (service != null) { +// ITargetDefinition dup = service.newTarget(); +// try { +// service.copyTargetDefinition(source, dup); +// dup.setName(NLS.bind("Copy of {0}", source.getName())); +// fTargets.add(dup); +// fTableViewer.refresh(); +// fTableViewer.setSelection(new StructuredSelection(dup)); +// } catch (CoreException ex) { +// setErrorMessage(ex.getMessage()); +// } +// } +// } +// }); + + fRemoveButton = SWTFactory.createPushButton(buttonComposite, "Remove", null); + fRemoveButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + IStructuredSelection selection = (IStructuredSelection) fTableViewer.getSelection(); + List selected = selection.toList(); + fRemoved.addAll(selected); + fTargets.removeAll(selected); + fTableViewer.refresh(); + // TODO: update selection + } + }); + + updateButtons(); + + if (service != null) { + try { + ITargetHandle handle = service.getWorkspaceTargetHandle(); + Iterator iterator = fTargets.iterator(); + while (iterator.hasNext()) { + ITargetDefinition target = (ITargetDefinition) iterator.next(); + if (target.getHandle().equals(handle)) { + fTableViewer.setCheckedElements(new Object[] {target}); + break; + } + } + } catch (CoreException e) { + setErrorMessage(e.getMessage()); + } + } + } + + /** + * Update enabled state of buttons + */ + protected void updateButtons() { + // update enabled state of buttons + IStructuredSelection selection = (IStructuredSelection) fTableViewer.getSelection(); + int size = selection.size(); + fRemoveButton.setEnabled(size > 0); + fEditButton.setEnabled(size == 1); + //fDuplicateButton.setEnabled(size == 1); + } + + /** + * Returns the target platform service. + * + * @return target platform service + */ + private ITargetPlatformService getTargetService() { + return (ITargetPlatformService) PDECore.getDefault().acquireService(ITargetPlatformService.class.getName()); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench) + */ + public void init(IWorkbench workbench) { + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.PreferencePage#performDefaults() + */ + public void performDefaults() { + // TODO + super.performDefaults(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.PreferencePage#performOk() + */ + public boolean performOk() { + ITargetPlatformService service = getTargetService(); + if (service == null) { + return false; + } + + // determine if default target has changed + ITargetDefinition toLoad = null; + boolean load = false; + try { + ITargetHandle prev = service.getWorkspaceTargetHandle(); + ITargetHandle currH = null; + ITargetDefinition currD = null; + Object[] elements = fTableViewer.getCheckedElements(); + if (elements.length > 0) { + currD = (ITargetDefinition) elements[0]; + currH = currD.getHandle(); + } + if (prev == null) { + if (currH != null) { + toLoad = currD; + load = true; + } + } else { + if (currH == null) { + // load empty + load = true; + } else if (!prev.equals(currH)) { + toLoad = currD; + load = true; + } else { + ITargetDefinition original = prev.getTargetDefinition(); + // TODO: should just check for structural changes + if (((TargetDefinition) original).isContentEqual(currD)) { + load = false; + } else { + load = true; + toLoad = currD; + } + } + } + } catch (CoreException e) { + ErrorDialog.openError(getShell(), "Error", "Unable to set workspace target platform", e.getStatus()); + return false; + } + + // Remove any definitions that have been removed + // TODO should we prompt? (only if workspace files?) + Iterator iterator = fRemoved.iterator(); + while (iterator.hasNext()) { + ITargetDefinition target = (ITargetDefinition) iterator.next(); + try { + service.deleteTarget(target.getHandle()); + } catch (CoreException e) { + ErrorDialog.openError(getShell(), "Error", "Unable to delete target definition", e.getStatus()); + return false; + } + } + // save others that are dirty + iterator = fTargets.iterator(); + while (iterator.hasNext()) { + ITargetDefinition def = (ITargetDefinition) iterator.next(); + boolean save = true; + if (def.getHandle().exists()) { + try { + ITargetDefinition original = def.getHandle().getTargetDefinition(); + if (((TargetDefinition) original).isContentEqual(def)) { + save = false; + } + } catch (CoreException e) { + // failed to generate original + setErrorMessage(e.getMessage()); + return false; + } + } + if (save) { + try { + service.saveTargetDefinition(def); + } catch (CoreException e) { + setErrorMessage(e.getMessage()); + return false; + } + } + } + + // set workspace target if required + if (load) { + // TODO: prompt to warn of build? (like JRE page) + Job job = new LoadTargetDefinitionJob(toLoad); + job.schedule(); + } + + return super.performOk(); + } + +} Index: src/org/eclipse/pde/internal/ui/wizards/target/TargetDefinitionEnvironmentPage.java =================================================================== RCS file: src/org/eclipse/pde/internal/ui/wizards/target/TargetDefinitionEnvironmentPage.java diff -N src/org/eclipse/pde/internal/ui/wizards/target/TargetDefinitionEnvironmentPage.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/pde/internal/ui/wizards/target/TargetDefinitionEnvironmentPage.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,634 @@ +/******************************************************************************* + * Copyright (c) 2009 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.ui.wizards.target; + +import java.util.*; +import org.eclipse.core.runtime.*; +import org.eclipse.debug.ui.StringVariableSelectionDialog; +import org.eclipse.equinox.internal.provisional.frameworkadmin.BundleInfo; +import org.eclipse.jdt.launching.JavaRuntime; +import org.eclipse.jdt.launching.environments.IExecutionEnvironment; +import org.eclipse.jdt.launching.environments.IExecutionEnvironmentsManager; +import org.eclipse.jface.viewers.*; +import org.eclipse.jface.window.Window; +import org.eclipse.osgi.service.resolver.BundleDescription; +import org.eclipse.pde.core.plugin.IPluginModelBase; +import org.eclipse.pde.core.plugin.PluginRegistry; +import org.eclipse.pde.internal.core.ICoreConstants; +import org.eclipse.pde.internal.core.PDECore; +import org.eclipse.pde.internal.core.target.provisional.ITargetDefinition; +import org.eclipse.pde.internal.core.util.VMUtil; +import org.eclipse.pde.internal.ui.*; +import org.eclipse.pde.internal.ui.elements.DefaultTableProvider; +import org.eclipse.pde.internal.ui.util.LocaleUtil; +import org.eclipse.pde.internal.ui.util.SWTUtil; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.*; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.*; +import org.eclipse.ui.dialogs.ElementListSelectionDialog; + +/** + * Page to edit environment and JRE settings for a target definition + */ +public class TargetDefinitionEnvironmentPage extends TargetDefinitionPage { + + // Environment pull-downs + private Combo fOSCombo; + private Combo fWSCombo; + private Combo fArchCombo; + private Combo fNLCombo; + + // Choices for each pull-down + private TreeSet fNLChoices; + private TreeSet fOSChoices; + private TreeSet fWSChoices; + private TreeSet fArchChoices; + + // JRE section + private Button fDefaultJREButton; + private Button fNamedJREButton; + private Button fExecEnvButton; + private Combo fNamedJREsCombo; + private Combo fExecEnvsCombo; + private TreeSet fExecEnvChoices; + + // argument controls + private Text fProgramArgs; + private Text fVMArgs; + private Button fAppendLauncherArgs; + + // implicit dependencies tab + private TableViewer fElementViewer; + private Button fAddButton; + private Button fRemoveButton; + private Button fRemoveAllButton; + + /** + * + * @param definition target definition to edit + */ + protected TargetDefinitionEnvironmentPage(ITargetDefinition definition) { + super("targetEnvironment", definition); + setTitle("Target Settings"); + setDescription("Edit the environment, arguments, and implicit dependencies for a target."); + setImageDescriptor(PDEPluginImages.DESC_TARGET_WIZ); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite parent) { + Composite comp = new Composite(parent, SWT.NONE); + comp.setLayout(new GridLayout(1, true)); + comp.setLayoutData(new GridData(GridData.FILL_BOTH)); + setControl(comp); + TabFolder tabs = new TabFolder(comp, SWT.NONE); + tabs.setLayoutData(new GridData(GridData.FILL_BOTH)); + + TabItem envTab = new TabItem(tabs, SWT.NONE); + envTab.setText("Environment"); + + Composite container = new Composite(tabs, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.verticalSpacing = 15; + container.setLayout(layout); + container.setLayoutData(new GridData(GridData.FILL_BOTH)); + + createTargetEnvironmentGroup(container); + createJREGroup(container); + envTab.setControl(container); + + TabItem argsTab = new TabItem(tabs, SWT.NONE); + argsTab.setText("Arguments"); + argsTab.setControl(createArgumentsGroup(tabs)); + + TabItem depTab = new TabItem(tabs, SWT.NONE); + depTab.setText("Implicit Dependencies"); + depTab.setControl(createImplicitTabContents(tabs)); + + targetChanged(getTargetDefinition()); + } + + private void createTargetEnvironmentGroup(Composite container) { + Group group = new Group(container, SWT.NULL); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + group.setLayout(layout); + group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + group.setText(PDEUIMessages.EnvironmentBlock_targetEnv); + + initializeChoices(); + + Label label = new Label(group, SWT.NULL); + label.setText(PDEUIMessages.Preferences_TargetEnvironmentPage_os); + + fOSCombo = new Combo(group, SWT.SINGLE | SWT.BORDER); + fOSCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + fOSCombo.setItems((String[]) fOSChoices.toArray(new String[fOSChoices.size()])); + fOSCombo.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + getTargetDefinition().setOS(getModelValue(fOSCombo.getText())); + } + }); + + label = new Label(group, SWT.NULL); + label.setText(PDEUIMessages.Preferences_TargetEnvironmentPage_ws); + + fWSCombo = new Combo(group, SWT.SINGLE | SWT.BORDER); + fWSCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + fWSCombo.setItems((String[]) fWSChoices.toArray(new String[fWSChoices.size()])); + fWSCombo.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + getTargetDefinition().setWS(getModelValue(fWSCombo.getText())); + } + }); + + label = new Label(group, SWT.NULL); + label.setText(PDEUIMessages.Preferences_TargetEnvironmentPage_arch); + + fArchCombo = new Combo(group, SWT.SINGLE | SWT.BORDER); + fArchCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + fArchCombo.setItems((String[]) fArchChoices.toArray(new String[fArchChoices.size()])); + fArchCombo.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + getTargetDefinition().setArch(getModelValue(fArchCombo.getText())); + } + }); + + label = new Label(group, SWT.NULL); + label.setText(PDEUIMessages.Preferences_TargetEnvironmentPage_nl); + + fNLCombo = new Combo(group, SWT.SINGLE | SWT.BORDER); + fNLCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + fNLCombo.setItems((String[]) fNLChoices.toArray(new String[fNLChoices.size()])); + fNLCombo.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + String value = fNLCombo.getText(); + int index = value.indexOf("-"); //$NON-NLS-1$ + if (index > 0) + value = value.substring(0, index); + getTargetDefinition().setNL(getModelValue(value)); + } + }); + + } + + /** + * Returns the given string or null if empty to set a value in the + * target definition. + * + * @param value + * @return + */ + private String getModelValue(String value) { + if (value != null) { + value = value.trim(); + if (value.length() == 0) { + return null; + } + } + return value; + } + + private void addExtraChoices(Set set, String preference) { + StringTokenizer tokenizer = new StringTokenizer(preference, ","); //$NON-NLS-1$ + while (tokenizer.hasMoreTokens()) { + set.add(tokenizer.nextToken().trim()); + } + } + + private void initializeChoices() { + Preferences preferences = PDECore.getDefault().getPluginPreferences(); + + fOSChoices = new TreeSet(); + String[] os = Platform.knownOSValues(); + for (int i = 0; i < os.length; i++) + fOSChoices.add(os[i]); + addExtraChoices(fOSChoices, preferences.getString(ICoreConstants.OS_EXTRA)); + + fWSChoices = new TreeSet(); + String[] ws = Platform.knownWSValues(); + for (int i = 0; i < ws.length; i++) + fWSChoices.add(ws[i]); + addExtraChoices(fWSChoices, preferences.getString(ICoreConstants.WS_EXTRA)); + + fArchChoices = new TreeSet(); + String[] arch = Platform.knownOSArchValues(); + for (int i = 0; i < arch.length; i++) + fArchChoices.add(arch[i]); + addExtraChoices(fArchChoices, preferences.getString(ICoreConstants.ARCH_EXTRA)); + + fNLChoices = new TreeSet(); + initializeAllLocales(); + } + + private void initializeAllLocales() { + Preferences preferences = PDECore.getDefault().getPluginPreferences(); + String[] nl = LocaleUtil.getLocales(); + for (int i = 0; i < nl.length; i++) + fNLChoices.add(nl[i]); + addExtraChoices(fNLChoices, preferences.getString(ICoreConstants.NL_EXTRA)); + } + + private void createJREGroup(Composite container) { + Group group = new Group(container, SWT.NULL); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + group.setLayout(layout); + group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + group.setText(PDEUIMessages.EnvironmentBlock_jreTitle); + + initializeJREValues(); + + Label label = new Label(group, SWT.WRAP); + label.setText(PDEUIMessages.JRESection_description); + GridData data = new GridData(GridData.FILL_HORIZONTAL); + data.verticalAlignment = SWT.TOP; + data.horizontalSpan = 2; + label.setLayoutData(data); + + fDefaultJREButton = new Button(group, SWT.RADIO); + fDefaultJREButton.setText(PDEUIMessages.JRESection_defaultJRE); + GridData gd = new GridData(); + gd.horizontalSpan = 2; + fDefaultJREButton.setLayoutData(gd); + fDefaultJREButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + updateJREWidgets(); + getTargetDefinition().setJREContainer(JavaRuntime.newDefaultJREContainerPath()); + } + }); + + fNamedJREButton = new Button(group, SWT.RADIO); + fNamedJREButton.setText(PDEUIMessages.JRESection_JREName); + fNamedJREButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + updateJREWidgets(); + getTargetDefinition().setJREContainer(JavaRuntime.newJREContainerPath(VMUtil.getVMInstall(fNamedJREsCombo.getText()))); + } + }); + + fNamedJREsCombo = new Combo(group, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY); + fNamedJREsCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + String[] installs = VMUtil.getVMInstallNames(); + fNamedJREsCombo.setItems(installs); + fNamedJREsCombo.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + getTargetDefinition().setJREContainer(JavaRuntime.newJREContainerPath(VMUtil.getVMInstall(fNamedJREsCombo.getText()))); + } + }); + + fExecEnvButton = new Button(group, SWT.RADIO); + fExecEnvButton.setText(PDEUIMessages.JRESection_ExecutionEnv); + fExecEnvButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + updateJREWidgets(); + getTargetDefinition().setJREContainer(JavaRuntime.newJREContainerPath(VMUtil.getExecutionEnvironment(fExecEnvsCombo.getText()))); + } + }); + + fExecEnvsCombo = new Combo(group, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY); + fExecEnvsCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + fExecEnvsCombo.setItems((String[]) fExecEnvChoices.toArray(new String[fExecEnvChoices.size()])); + fExecEnvsCombo.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + getTargetDefinition().setJREContainer(JavaRuntime.newJREContainerPath(VMUtil.getExecutionEnvironment(fExecEnvsCombo.getText()))); + } + }); + + } + + /** + * Initializes the combo with possible execution enviroments + */ + protected void initializeJREValues() { + fExecEnvChoices = new TreeSet(); + IExecutionEnvironmentsManager manager = JavaRuntime.getExecutionEnvironmentsManager(); + IExecutionEnvironment[] envs = manager.getExecutionEnvironments(); + for (int i = 0; i < envs.length; i++) + fExecEnvChoices.add(envs[i].getId()); + } + + protected void updateJREWidgets() { + fNamedJREsCombo.setEnabled(fNamedJREButton.getSelection()); + fExecEnvsCombo.setEnabled(fExecEnvButton.getSelection()); + } + + private Control createArgumentsGroup(Composite parent) { + Composite container = new Composite(parent, SWT.NONE); + container.setLayout(new GridLayout()); + + Label description = new Label(container, SWT.WRAP); + description.setText(PDEUIMessages.JavaArgumentsTab_description); + GridData gd = new GridData(); + gd.widthHint = 450; + description.setLayoutData(gd); + + Group programGroup = new Group(container, SWT.NONE); + programGroup.setLayout(new GridLayout()); + programGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + programGroup.setText(PDEUIMessages.JavaArgumentsTab_progamArgsGroup); + + fProgramArgs = new Text(programGroup, SWT.MULTI | SWT.WRAP | SWT.BORDER | SWT.V_SCROLL); + gd = new GridData(GridData.FILL_BOTH); + gd.widthHint = 450; + gd.heightHint = 60; + fProgramArgs.setLayoutData(gd); + fProgramArgs.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + getTargetDefinition().setProgramArguments(fProgramArgs.getText().trim()); + } + }); + + Button programVars = new Button(programGroup, SWT.NONE); + programVars.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END)); + programVars.setText(PDEUIMessages.JavaArgumentsTab_programVariables); + programVars.addSelectionListener(getListener(fProgramArgs)); + + Group vmGroup = new Group(container, SWT.NONE); + vmGroup.setLayout(new GridLayout(2, false)); + vmGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + vmGroup.setText(PDEUIMessages.JavaArgumentsTab_vmArgsGroup); + + fVMArgs = new Text(vmGroup, SWT.MULTI | SWT.WRAP | SWT.BORDER | SWT.V_SCROLL); + gd = new GridData(GridData.FILL_BOTH); + gd.widthHint = 450; + gd.heightHint = 60; + gd.horizontalSpan = 2; + fVMArgs.setLayoutData(gd); + fVMArgs.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + getTargetDefinition().setVMArguments(fVMArgs.getText().trim()); + } + }); + + fAppendLauncherArgs = new Button(vmGroup, SWT.CHECK); + fAppendLauncherArgs.setText(PDEUIMessages.JavaArgumentsTab_appendLauncherIni); + + Button vmVars = new Button(vmGroup, SWT.NONE); + vmVars.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END)); + vmVars.setText(PDEUIMessages.JavaArgumentsTab_vmVariables); + vmVars.addSelectionListener(getListener(fVMArgs)); + return container; + } + + protected SelectionListener getListener(final Text textControl) { + return new SelectionListener() { + public void widgetSelected(SelectionEvent e) { + StringVariableSelectionDialog dialog = new StringVariableSelectionDialog(getShell()); + dialog.open(); + String variable = dialog.getVariableExpression(); + if (variable != null) { + textControl.insert(variable); + } + } + + public void widgetDefaultSelected(SelectionEvent e) { + } + }; + } + + private Control createImplicitTabContents(Composite parent) { + Composite container = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(2, false); + container.setLayout(layout); + container.setLayoutData(new GridData(GridData.FILL_BOTH)); + + createImpLabel(container); + createImpTable(container); + createImpButtons(container); + // TODO: PlatformUI.getWorkbench().getHelpSystem().setHelp(container, IHelpContextIds.IMPLICIT_PLUGINS_PREFERENCE_PAGE); + return container; + } + + private void createImpLabel(Composite container) { + Label label = new Label(container, SWT.NONE); + label.setText(PDEUIMessages.TargetImplicitPluginsTab_desc); + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + gd.horizontalSpan = 2; + label.setLayoutData(gd); + } + + private void createImpTable(Composite container) { + fElementViewer = new TableViewer(container, SWT.SINGLE | SWT.V_SCROLL | SWT.BORDER); + GridData gd = new GridData(GridData.FILL_BOTH); + fElementViewer.getControl().setLayoutData(gd); + fElementViewer.setContentProvider(new DefaultTableProvider() { + public Object[] getElements(Object inputElement) { + BundleInfo[] bundles = getTargetDefinition().getImplicitDependencies(); + if (bundles == null) { + return new BundleInfo[0]; + } + return bundles; + } + }); + fElementViewer.setLabelProvider(new LabelProvider() { + public String getText(Object element) { + if (element instanceof BundleInfo) { + return ((BundleInfo) element).getSymbolicName(); + } + return super.getText(element); + } + // TODO: labels + }); + fElementViewer.setInput(PDEPlugin.getDefault()); + fElementViewer.setComparator(new ViewerComparator() { + public int compare(Viewer viewer, Object e1, Object e2) { + BundleInfo bundle1 = (BundleInfo) e1; + BundleInfo bundle2 = (BundleInfo) e2; + return super.compare(viewer, bundle1.getSymbolicName(), bundle2.getSymbolicName()); + } + }); + fElementViewer.addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + updateImpButtons(); + } + }); + fElementViewer.getTable().addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + if (e.character == SWT.DEL && e.stateMask == 0) { + handleRemove(); + } + } + }); + + } + + private void createImpButtons(Composite container) { + Composite buttonContainer = new Composite(container, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.marginWidth = layout.marginHeight = 0; + buttonContainer.setLayout(layout); + buttonContainer.setLayoutData(new GridData(GridData.FILL_VERTICAL)); + + fAddButton = new Button(buttonContainer, SWT.PUSH); + fAddButton.setText(PDEUIMessages.SourceBlock_add); + fAddButton.setLayoutData(new GridData(GridData.FILL | GridData.VERTICAL_ALIGN_BEGINNING)); + SWTUtil.setButtonDimensionHint(fAddButton); + fAddButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + handleAdd(); + } + }); + + fRemoveButton = new Button(buttonContainer, SWT.PUSH); + fRemoveButton.setText(PDEUIMessages.SourceBlock_remove); + fRemoveButton.setLayoutData(new GridData(GridData.FILL | GridData.VERTICAL_ALIGN_BEGINNING)); + SWTUtil.setButtonDimensionHint(fRemoveButton); + fRemoveButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + handleRemove(); + } + }); + + fRemoveAllButton = new Button(buttonContainer, SWT.PUSH); + fRemoveAllButton.setText(PDEUIMessages.TargetImplicitPluginsTab_removeAll3); + fRemoveAllButton.setLayoutData(new GridData(GridData.FILL | GridData.VERTICAL_ALIGN_BEGINNING)); + SWTUtil.setButtonDimensionHint(fRemoveAllButton); + fRemoveAllButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + handleRemoveAll(); + } + }); + updateImpButtons(); + } + + protected void handleAdd() { + ElementListSelectionDialog dialog = new ElementListSelectionDialog(PDEPlugin.getActiveWorkbenchShell(), PDEPlugin.getDefault().getLabelProvider()); + + dialog.setElements(getValidBundles()); + dialog.setTitle(PDEUIMessages.PluginSelectionDialog_title); + dialog.setMessage(PDEUIMessages.PluginSelectionDialog_message); + dialog.setMultipleSelection(true); + if (dialog.open() == Window.OK) { + Object[] models = dialog.getResult(); + ArrayList pluginsToAdd = new ArrayList(); + for (int i = 0; i < models.length; i++) { + BundleDescription desc = ((BundleDescription) models[i]); + pluginsToAdd.add(new BundleInfo(desc.getSymbolicName(), null, null, BundleInfo.NO_LEVEL, false)); + } + Set allDependencies = new HashSet(); + allDependencies.addAll(pluginsToAdd); + BundleInfo[] currentBundles = getTargetDefinition().getImplicitDependencies(); + if (currentBundles != null) { + allDependencies.addAll(Arrays.asList(currentBundles)); + } + getTargetDefinition().setImplicitDependencies((BundleInfo[]) allDependencies.toArray(new BundleInfo[allDependencies.size()])); + fElementViewer.refresh(); + // update target + } + } + + /** + * Gets a list of all the bundles that can be added as implicit dependencies + * @return list of possible dependencies + */ + protected BundleDescription[] getValidBundles() { + BundleInfo[] current = getTargetDefinition().getImplicitDependencies(); + Set currentBundles = new HashSet(); + if (current != null) { + for (int i = 0; i < current.length; i++) { + currentBundles.add(current[i].getSymbolicName()); + } + } + + // TODO Do we want to get the possible models from the plugin registry? Would be better to get the bundles from the editor's target definition? + IPluginModelBase[] models = PluginRegistry.getActiveModels(false); + Set result = new HashSet(); + for (int i = 0; i < models.length; i++) { + BundleDescription desc = models[i].getBundleDescription(); + if (desc != null) { + if (!currentBundles.contains(desc.getSymbolicName())) + result.add(desc); + } + } + + return (BundleDescription[]) result.toArray((new BundleDescription[result.size()])); + } + + private void handleRemove() { + LinkedList bundles = new LinkedList(); + bundles.addAll(Arrays.asList(getTargetDefinition().getImplicitDependencies())); + Object[] removeBundles = ((IStructuredSelection) fElementViewer.getSelection()).toArray(); + if (removeBundles.length > 0) { + for (int i = 0; i < removeBundles.length; i++) { + if (removeBundles[i] instanceof BundleInfo) { + bundles.remove(removeBundles[i]); + } + } + getTargetDefinition().setImplicitDependencies((BundleInfo[]) bundles.toArray((new BundleInfo[bundles.size()]))); + fElementViewer.refresh(); + } + } + + private void handleRemoveAll() { + getTargetDefinition().setImplicitDependencies(null); + fElementViewer.refresh(); + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.ui.wizards.target.TargetDefinitionPage#targetChanged() + */ + protected void targetChanged(ITargetDefinition definition) { + super.targetChanged(definition); + if (definition != null) { + String presetValue = (definition.getOS() == null) ? "" : definition.getOS(); //$NON-NLS-1$ + fOSCombo.setText(presetValue); + presetValue = (definition.getWS() == null) ? "" : definition.getWS(); //$NON-NLS-1$ + fWSCombo.setText(presetValue); + presetValue = (definition.getArch() == null) ? "" : definition.getArch(); //$NON-NLS-1$ + fArchCombo.setText(presetValue); + presetValue = (definition.getNL() == null) ? "" : LocaleUtil.expandLocaleName(definition.getNL()); //$NON-NLS-1$ + fNLCombo.setText(presetValue); + + IPath jrePath = definition.getJREContainer(); + if (jrePath == null || jrePath.equals(JavaRuntime.newDefaultJREContainerPath())) { + fDefaultJREButton.setSelection(true); + } else { + String ee = JavaRuntime.getExecutionEnvironmentId(jrePath); + if (ee != null) { + fExecEnvButton.setSelection(true); + fExecEnvsCombo.select(fExecEnvsCombo.indexOf(ee)); + } else { + String vm = JavaRuntime.getVMInstallName(jrePath); + if (vm != null) { + fNamedJREButton.setSelection(true); + fNamedJREsCombo.select(fNamedJREsCombo.indexOf(vm)); + } + } + } + + if (fExecEnvsCombo.getSelectionIndex() == -1) + fExecEnvsCombo.setText(fExecEnvChoices.first().toString()); + + if (fNamedJREsCombo.getSelectionIndex() == -1) + fNamedJREsCombo.setText(VMUtil.getDefaultVMInstallName()); + + updateJREWidgets(); + + presetValue = (definition.getProgramArguments() == null) ? "" : definition.getProgramArguments(); //$NON-NLS-1$ + fProgramArgs.setText(presetValue); + presetValue = (definition.getVMArguments() == null) ? "" : definition.getVMArguments(); //$NON-NLS-1$ + fVMArgs.setText(presetValue); + + } + } + + private void updateImpButtons() { + boolean empty = fElementViewer.getSelection().isEmpty(); + fRemoveButton.setEnabled(!empty); + boolean hasElements = fElementViewer.getTable().getItemCount() > 0; + fRemoveAllButton.setEnabled(hasElements); + } + +} Index: src/org/eclipse/pde/internal/ui/wizards/target/EditTargetDefinitionWizard.java =================================================================== RCS file: src/org/eclipse/pde/internal/ui/wizards/target/EditTargetDefinitionWizard.java diff -N src/org/eclipse/pde/internal/ui/wizards/target/EditTargetDefinitionWizard.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/pde/internal/ui/wizards/target/EditTargetDefinitionWizard.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2009 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.ui.wizards.target; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.wizard.IWizardPage; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.pde.internal.core.target.provisional.ITargetDefinition; +import org.eclipse.pde.internal.core.target.provisional.ITargetPlatformService; +import org.eclipse.pde.internal.ui.PDEPlugin; + +/** + * Wizard to edit a target definition + */ +public class EditTargetDefinitionWizard extends Wizard { + + /** + * The target definition being edited - a copy of the original + */ + private ITargetDefinition fDefinition; + + /** + * The original target definition that was to be edited. We create + * a copy in case the user cancels the operation. + */ + private ITargetDefinition fOriginal; + + /* (non-Javadoc) + * @see org.eclipse.jface.wizard.Wizard#performFinish() + */ + public boolean performFinish() { + // TODO check if any changes first + ITargetPlatformService service = TargetDefinitionPage.getTargetService(); + if (service != null) { + try { + service.copyTargetDefinition(fDefinition, fOriginal); + } catch (CoreException e) { + // TODO set error message + return false; + } + } + return true; + } + + /** + * Constructs a wizard to edit the given definition. + * + * @param definition + */ + public EditTargetDefinitionWizard(ITargetDefinition definition) { + setTargetDefinition(definition); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.wizard.Wizard#addPages() + */ + public void addPages() { + addPage(new TargetDefinitionContentPage(fDefinition)); + addPage(new TargetDefinitionEnvironmentPage(fDefinition)); + } + + /** + * Sets the target definition to be edited. Will delegate to pages to + * refresh controls if already created. + * + * @param definition target definition + */ + public void setTargetDefinition(ITargetDefinition definition) { + fOriginal = definition; + ITargetPlatformService service = TargetDefinitionPage.getTargetService(); + if (service != null) { + fDefinition = service.newTarget(); + try { + service.copyTargetDefinition(definition, fDefinition); + IWizardPage[] pages = getPages(); + for (int i = 0; i < pages.length; i++) { + ((TargetDefinitionPage) pages[i]).targetChanged(fDefinition); + } + } catch (CoreException e) { + // TODO: show error message + PDEPlugin.log(e); + } + } + } + + /** + * Returns the target definition being edited + * + * @return target definition + */ + public ITargetDefinition getTargetDefinition() { + return fDefinition; + } +} Index: src/org/eclipse/pde/internal/ui/wizards/target/TargetDefinitionContentPage.java =================================================================== RCS file: src/org/eclipse/pde/internal/ui/wizards/target/TargetDefinitionContentPage.java diff -N src/org/eclipse/pde/internal/ui/wizards/target/TargetDefinitionContentPage.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/pde/internal/ui/wizards/target/TargetDefinitionContentPage.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright (c) 2009 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.ui.wizards.target; + +import org.eclipse.pde.internal.core.target.provisional.ITargetDefinition; +import org.eclipse.pde.internal.ui.PDEPluginImages; +import org.eclipse.pde.internal.ui.shared.target.BundleContainerTable; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.*; + +/** + * + */ +public class TargetDefinitionContentPage extends TargetDefinitionPage { + + private Text fNameText; + private Text fDescriptionText; + private BundleContainerTable fTable; + + /** + * @param pageName + */ + public TargetDefinitionContentPage(ITargetDefinition target) { + super("targetContent", target); + setTitle("Target Content"); + setDescription("Edit the name, description, and bundles contained in a target."); + setImageDescriptor(PDEPluginImages.DESC_TARGET_WIZ); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite parent) { + Composite comp = new Composite(parent, SWT.NONE); + comp.setLayout(new GridLayout(1, true)); + comp.setLayoutData(new GridData(GridData.FILL_BOTH)); + + Group group = new Group(comp, SWT.NONE); + group.setText("Identification:"); + group.setLayout(new GridLayout(2, false)); + group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + Label label = new Label(group, SWT.NONE); + label.setText("N&ame:"); + GridData gridData = new GridData(SWT.LEFT, SWT.TOP, false, false); + label.setLayoutData(gridData); + + fNameText = new Text(group, SWT.BORDER); + gridData = new GridData(SWT.FILL, SWT.TOP, true, false); + fNameText.setLayoutData(gridData); + fNameText.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + getTargetDefinition().setName(fNameText.getText().trim()); + } + }); + + label = new Label(group, SWT.NONE); + label.setText("Descri&ption:"); + gridData = new GridData(SWT.LEFT, SWT.TOP, false, false); + label.setLayoutData(gridData); + + fDescriptionText = new Text(group, SWT.BORDER); + gridData = new GridData(SWT.FILL, SWT.TOP, true, false); + fDescriptionText.setLayoutData(gridData); + fDescriptionText.addModifyListener(new ModifyListener() { + public void modifyText(ModifyEvent e) { + getTargetDefinition().setDescription(fDescriptionText.getText().trim()); + } + }); + + Group content = new Group(comp, SWT.NONE); + content.setText("C&ontent:"); + content.setLayout(new GridLayout(2, false)); + gridData = new GridData(GridData.FILL_BOTH); + gridData.widthHint = 200; + content.setLayoutData(gridData); + + fTable = BundleContainerTable.createTableInDialog(content); + setControl(comp); + targetChanged(getTargetDefinition()); + } + + /* (non-Javadoc) + * @see org.eclipse.pde.internal.ui.wizards.target.TargetDefinitionPage#targetChanged() + */ + protected void targetChanged(ITargetDefinition definition) { + super.targetChanged(definition); + if (definition != null) { + fNameText.setText(definition.getName()); + String des = definition.getDescription(); + if (des == null) { + des = ""; //$NON-NLS-1$ + } + fDescriptionText.setText(des); + fTable.setInput(definition); + } + } +} #P org.eclipse.pde.ui.tests Index: src/org/eclipse/pde/ui/tests/target/TargetDefinitionTests.java =================================================================== RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/target/TargetDefinitionTests.java,v retrieving revision 1.8 diff -u -r1.8 TargetDefinitionTests.java --- src/org/eclipse/pde/ui/tests/target/TargetDefinitionTests.java 21 Jan 2009 20:49:03 -0000 1.8 +++ src/org/eclipse/pde/ui/tests/target/TargetDefinitionTests.java 22 Jan 2009 22:27:47 -0000 @@ -1,1244 +1,1195 @@ -/******************************************************************************* - * Copyright (c) 2008, 2009 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.ui.tests.target; - -import org.eclipse.core.runtime.CoreException; - -import org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer; - -import org.eclipse.pde.internal.core.target.impl.ProfileBundleContainer; - -import org.eclipse.pde.internal.core.target.impl.FeatureBundleContainer; - -import java.io.*; -import java.net.URL; -import java.util.*; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; -import junit.framework.TestCase; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.*; -import org.eclipse.core.variables.VariablesPlugin; -import org.eclipse.equinox.internal.provisional.frameworkadmin.BundleInfo; -import org.eclipse.jdt.launching.JavaRuntime; -import org.eclipse.pde.core.plugin.IPluginModelBase; -import org.eclipse.pde.core.plugin.TargetPlatform; -import org.eclipse.pde.internal.core.*; -import org.eclipse.pde.internal.core.target.impl.DirectoryBundleContainer; -import org.eclipse.pde.internal.core.target.impl.TargetDefinitionPersistenceHelper; -import org.eclipse.pde.internal.core.target.provisional.*; -import org.eclipse.pde.internal.ui.tests.macro.MacroPlugin; -import org.osgi.framework.ServiceReference; - -/** - * Tests for target definitions. - * - * @since 3.5 - */ -public class TargetDefinitionTests extends TestCase { - - /** - * Retrieves all bundles (source and code) in the given target definition - * returning them as a set of URLs. - * - * @param target target definition - * @return all bundle URLs - */ - protected Set getAllBundleURLs(ITargetDefinition target) throws Exception { - BundleInfo[] code = target.resolveBundles(null); - BundleInfo[] source = target.resolveSourceBundles(null); - Set urls = new HashSet(code.length + source.length); - for (int i = 0; i < code.length; i++) { - urls.add(new File(code[i].getLocation()).toURL()); - } - for (int i = 0; i < source.length; i++) { - urls.add(new File(source[i].getLocation()).toURL()); - } - return urls; - } - - /** - * Retrieves all bundles (source and code) in the given target definition - * returning them as a list of BundleInfos. - * - * @param target target definition - * @return all BundleInfos - */ - protected List getAllBundleInfos(ITargetDefinition target) throws Exception { - BundleInfo[] code = target.resolveBundles(null); - BundleInfo[] source = target.resolveSourceBundles(null); - List list = new ArrayList(code.length + source.length); - for (int i = 0; i < code.length; i++) { - list.add(code[i]); - } - for (int i = 0; i < source.length; i++) { - list.add(source[i]); - } - return list; - } - - /** - * Collects all bundle symbolic names into a set. - * - * @param infos bundles - * @return bundle symbolic names - */ - protected Set collectAllSymbolicNames(List infos) { - Set set = new HashSet(infos.size()); - Iterator iterator = infos.iterator(); - while (iterator.hasNext()) { - BundleInfo info = (BundleInfo) iterator.next(); - set.add(info.getSymbolicName()); - } - return set; - } - - /** - * Returns the resolved location of the specified bundle container. - * - * @param container bundle container - * @return resolved location - * @throws CoreException - */ - protected String getResolvedLocation(IBundleContainer container) throws CoreException { - return ((AbstractBundleContainer)container).getLocation(true); - } - - /** - * Extracts the classic plug-ins archive, if not already done, and returns a path to the - * root directory containing the plug-ins. - * - * @return path to the plug-ins directory - * @throws Exception - */ - protected IPath extractClassicPlugins() throws Exception { - // extract the 3.0.2 skeleton - IPath stateLocation = MacroPlugin.getDefault().getStateLocation(); - IPath location = stateLocation.append("classic-plugins"); - if (location.toFile().exists()) { - return location; - } - URL zipURL = MacroPlugin.getBundleContext().getBundle().getEntry("/tests/targets/classic-plugins.zip"); - Path zipPath = new Path(new File(FileLocator.toFileURL(zipURL).getFile()).getAbsolutePath()); - ZipFile zipFile = new ZipFile(zipPath.toFile()); - Enumeration entries = zipFile.entries(); - while (entries.hasMoreElements()) { - ZipEntry entry = (ZipEntry) entries.nextElement(); - if (!entry.isDirectory()) { - IPath entryPath = stateLocation.append(entry.getName()); - File dir = entryPath.removeLastSegments(1).toFile(); - dir.mkdirs(); - File file = entryPath.toFile(); - file.createNewFile(); - InputStream inputStream = new BufferedInputStream(zipFile.getInputStream(entry)); - byte[] bytes = getInputStreamAsByteArray(inputStream, -1); - inputStream.close(); - BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(file)); - outputStream.write(bytes); - outputStream.close(); - } - } - zipFile.close(); - return location; - } - - /** - * Returns the target platform service or null if none - * - * @return target platform service - */ - protected ITargetPlatformService getTargetService() { - ServiceReference reference = MacroPlugin.getBundleContext().getServiceReference(ITargetPlatformService.class.getName()); - assertNotNull("Missing target platform service", reference); - if (reference == null) - return null; - return (ITargetPlatformService) MacroPlugin.getBundleContext().getService(reference); - } - - /** - * Returns a default target platform that takes target weaving into account - * if in a second instance of Eclipse. This allows the target platform to be - * reset after changing it in a test. - * - * @return default settings for target platform - */ - protected ITargetDefinition getDefaultTargetPlatorm() { - ITargetDefinition definition = getTargetService().newTarget(); - IBundleContainer container = getTargetService().newProfileContainer(TargetPlatform.getDefaultLocation(), - new File(Platform.getConfigurationLocation().getURL().getFile()).getAbsolutePath()); - definition.setBundleContainers(new IBundleContainer[]{container}); - return definition; - } - - /** - * Used to reset the target platform to original settings after a test that changes - * the target platform. - * @throws CoreException - */ - protected void resetTargetPlatform() throws CoreException { - ITargetDefinition definition = getDefaultTargetPlatorm(); - setTargetPlatform(definition); - } - - /** - * Sets the target platform based on the given definition. - * - * @param target target definition or null - * @throws CoreException - */ - protected void setTargetPlatform(ITargetDefinition target) throws CoreException { - LoadTargetDefinitionJob job = new LoadTargetDefinitionJob(target); - job.schedule(); - try { - job.join(); - } catch (InterruptedException e) { - assertFalse("Target platform reset interrupted", true); - } - ITargetHandle handle = null; - if (target != null) { - handle = target.getHandle(); - } - assertEquals("Wrong target platform handle preference setting", handle, getTargetService().getWorkspaceTargetHandle()); - } - - /** - * Tests that resetting the target platform should work OK (i.e. is equivalent to the - * models in the default target platform). - * - * @throws CoreException - */ - public void testResetTargetPlatform() throws Exception { - ITargetDefinition definition = getDefaultTargetPlatorm(); - Set urls = getAllBundleURLs(definition); - - // current platform - IPluginModelBase[] models = TargetPlatformHelper.getPDEState().getTargetModels(); - - // should be equivalent - assertEquals("Should have same number of bundles", urls.size(), models.length); - for (int i = 0; i < models.length; i++) { - String location = models[i].getInstallLocation(); - assertTrue("Missing plug-in " + location, urls.contains(new File(location).toURL())); - } - } - - /** - * Tests that a target definition equivalent to the default target platform - * contains the same bundles as the default target platform (this is an - * explicit location with no target weaving). - * - * @throws Exception - */ - public void testDefaultTargetPlatform() throws Exception { - // the new way - ITargetDefinition definition = getTargetService().newTarget(); - IBundleContainer container = getTargetService().newProfileContainer(TargetPlatform.getDefaultLocation(), null); - definition.setBundleContainers(new IBundleContainer[]{container}); - Set urls = getAllBundleURLs(definition); - - // the old way - IPath location = new Path(TargetPlatform.getDefaultLocation()); - URL[] pluginPaths = P2Utils.readBundlesTxt(location.toOSString(), location.append("configuration").toFile().toURL()); - assertEquals("Should have same number of bundles", pluginPaths.length, urls.size()); - for (int i = 0; i < pluginPaths.length; i++) { - URL url = pluginPaths[i]; - assertTrue("Missing plug-in " + url.toString(), urls.contains(url)); - } - - } - - /** - * Tests that a target definition based on the default target platform - * restricted to a subset of bundles contains the right set. - * - * @throws Exception - */ - public void testRestrictedDefaultTargetPlatform() throws Exception { - ITargetDefinition definition = getTargetService().newTarget(); - IBundleContainer container = getTargetService().newProfileContainer(TargetPlatform.getDefaultLocation(), null); - BundleInfo[] restrictions = new BundleInfo[]{ - new BundleInfo("org.eclipse.jdt.launching", null, null, BundleInfo.NO_LEVEL, false), - new BundleInfo("org.eclipse.jdt.debug", null, null, BundleInfo.NO_LEVEL, false) - }; - container.setRestrictions(restrictions); - definition.setBundleContainers(new IBundleContainer[]{container}); - List infos = getAllBundleInfos(definition); - - assertEquals("Wrong number of bundles", 2, infos.size()); - Set set = collectAllSymbolicNames(infos); - for (int i = 0; i < restrictions.length; i++) { - BundleInfo info = restrictions[i]; - set.remove(info.getSymbolicName()); - } - assertEquals("Wrong bundles", 0, set.size()); - - } - - /** - * Tests that a target definition based on the default target platform - * restricted to a subset of bundle versions contains the right set. - * - * @throws Exception - */ - public void testVersionRestrictedDefaultTargetPlatform() throws Exception { - ITargetDefinition definition = getTargetService().newTarget(); - IBundleContainer container = getTargetService().newProfileContainer(TargetPlatform.getDefaultLocation(), null); - definition.setBundleContainers(new IBundleContainer[]{container}); - List infos = getAllBundleInfos(definition); - // find right versions - String v1 = null; - String v2 = null; - Iterator iterator = infos.iterator(); - while (iterator.hasNext() && (v2 == null || v1 == null)) { - BundleInfo info = (BundleInfo) iterator.next(); - if (info.getSymbolicName().equals("org.eclipse.jdt.launching")) { - v1 = info.getVersion(); - } else if (info.getSymbolicName().equals("org.eclipse.jdt.debug")) { - v2 = info.getVersion(); - } - } - assertNotNull(v1); - assertNotNull(v2); - - BundleInfo[] restrictions = new BundleInfo[]{ - new BundleInfo("org.eclipse.jdt.launching", v1, null, BundleInfo.NO_LEVEL, false), - new BundleInfo("org.eclipse.jdt.debug", v2, null, BundleInfo.NO_LEVEL, false) - }; - container.setRestrictions(restrictions); - infos = getAllBundleInfos(definition); - - assertEquals("Wrong number of bundles", 2, infos.size()); - iterator = infos.iterator(); - while (iterator.hasNext()) { - BundleInfo info = (BundleInfo) iterator.next(); - if (info.getSymbolicName().equals("org.eclipse.jdt.launching")) { - assertEquals(v1, info.getVersion()); - } else if (info.getSymbolicName().equals("org.eclipse.jdt.debug")) { - assertEquals(v2, info.getVersion()); - } - } - } - - /** - * Tests that a target definition based on the default target platform - * restricted to a subset of bundles contains the right set. In this case - * empty, since the versions specified are bogus. - * - * @throws Exception - */ - public void testMissingVersionRestrictedDefaultTargetPlatform() throws Exception { - ITargetDefinition definition = getTargetService().newTarget(); - IBundleContainer container = getTargetService().newProfileContainer(TargetPlatform.getDefaultLocation(), null); - BundleInfo[] restrictions = new BundleInfo[]{ - new BundleInfo("org.eclipse.jdt.launching", "xyz", null, BundleInfo.NO_LEVEL, false), - new BundleInfo("org.eclipse.jdt.debug", "abc", null, BundleInfo.NO_LEVEL, false) - }; - container.setRestrictions(restrictions); - definition.setBundleContainers(new IBundleContainer[]{container}); - List infos = getAllBundleInfos(definition); - - assertEquals("Wrong number of bundles", 0, infos.size()); - } - - /** - * Tests that a target definition equivalent to the default target platform - * contains the same bundles as the default target platform (this is an - * explicit location with no target weaving), when created with a variable - * referencing ${eclipse_home} - * - * @throws Exception - */ - public void testEclipseHomeTargetPlatform() throws Exception { - // the new way - ITargetDefinition definition = getTargetService().newTarget(); - IBundleContainer container = getTargetService().newProfileContainer("${eclipse_home}", null); - definition.setBundleContainers(new IBundleContainer[]{container}); - Set urls = getAllBundleURLs(definition); - - // the old way - IPath location = new Path(TargetPlatform.getDefaultLocation()); - URL[] pluginPaths = P2Utils.readBundlesTxt(location.toOSString(), location.append("configuration").toFile().toURL()); - assertEquals("Should have same number of bundles", pluginPaths.length, urls.size()); - for (int i = 0; i < pluginPaths.length; i++) { - URL url = pluginPaths[i]; - assertTrue("Missing plug-in " + url.toString(), urls.contains(url)); - } - - } - - /** - * Tests that a target definition equivalent to the default target platform - * contains the same bundles as the default target platform (this is an - * explicit location with no target weaving), when created with a variable - * referencing ${eclipse_home}. - * - * @throws Exception - */ - public void testEclipseHomeTargetPlatformAndConfigurationArea() throws Exception { - // the new way - ITargetDefinition definition = getTargetService().newTarget(); - IBundleContainer container = getTargetService().newProfileContainer("${eclipse_home}", "${eclipse_home}/configuration"); - definition.setBundleContainers(new IBundleContainer[]{container}); - Set urls = getAllBundleURLs(definition); - - // the old way - IPath location = new Path(TargetPlatform.getDefaultLocation()); - URL[] pluginPaths = P2Utils.readBundlesTxt(location.toOSString(), location.append("configuration").toFile().toURL()); - assertEquals("Should have same number of bundles", pluginPaths.length, urls.size()); - for (int i = 0; i < pluginPaths.length; i++) { - URL url = pluginPaths[i]; - assertTrue("Missing plug-in " + url.toString(), urls.contains(url)); - } - - } - - /** - * Tests that a target definition equivalent to the default target platform - * contains the same bundles as the default target platform using the - * platform's configuration location (which will do target weaving). This - * is really only tested when run as a JUnit plug-in test suite from - * within Eclipse. - * - * @throws Exception - */ - public void testWovenTargetPlatform() throws Exception { - // the new way - ITargetDefinition definition = getTargetService().newTarget(); - IBundleContainer container = getTargetService().newProfileContainer(TargetPlatform.getDefaultLocation(), - new File(Platform.getConfigurationLocation().getURL().getFile()).getAbsolutePath()); - definition.setBundleContainers(new IBundleContainer[]{container}); - Set urls = getAllBundleURLs(definition); - - // the old way - URL[] pluginPaths = PluginPathFinder.getPluginPaths(TargetPlatform.getDefaultLocation()); - assertEquals("Should have same number of bundles", pluginPaths.length, urls.size()); - for (int i = 0; i < pluginPaths.length; i++) { - URL url = pluginPaths[i]; - assertTrue("Missing plug-in " + url.toString(), urls.contains(url)); - } - - } - - /** - * Tests that a bundle directory container is equivalent to scanning locations. - * - * @throws Exception - */ - public void testDirectoryBundleContainer() throws Exception { - // the new way - ITargetDefinition definition = getTargetService().newTarget(); - IBundleContainer container = getTargetService().newDirectoryContainer(TargetPlatform.getDefaultLocation() + "/plugins"); - definition.setBundleContainers(new IBundleContainer[]{container}); - Set urls = getAllBundleURLs(definition); - - Preferences store = PDECore.getDefault().getPluginPreferences(); - boolean restore = store.getBoolean(ICoreConstants.TARGET_PLATFORM_REALIZATION); - try { - store.setValue(ICoreConstants.TARGET_PLATFORM_REALIZATION, false); - // the old way - URL[] pluginPaths = PluginPathFinder.getPluginPaths(TargetPlatform.getDefaultLocation()); - assertEquals("Should have same number of bundles", pluginPaths.length, urls.size()); - for (int i = 0; i < pluginPaths.length; i++) { - URL url = pluginPaths[i]; - assertTrue("Missing plug-in " + url.toString(), urls.contains(url)); - } - } - finally { - store.setValue(ICoreConstants.TARGET_PLATFORM_REALIZATION, restore); - } - } - - /** - * Tests that a bundle directory container is equivalent to scanning locations - * when it uses a variable to specify its location. - * - * @throws Exception - */ - public void testVariableDirectoryBundleContainer() throws Exception { - // the new way - ITargetDefinition definition = getTargetService().newTarget(); - IBundleContainer container = getTargetService().newDirectoryContainer("${eclipse_home}/plugins"); - definition.setBundleContainers(new IBundleContainer[]{container}); - Set urls = getAllBundleURLs(definition); - - Preferences store = PDECore.getDefault().getPluginPreferences(); - boolean restore = store.getBoolean(ICoreConstants.TARGET_PLATFORM_REALIZATION); - try { - store.setValue(ICoreConstants.TARGET_PLATFORM_REALIZATION, false); - // the old way - URL[] pluginPaths = PluginPathFinder.getPluginPaths(TargetPlatform.getDefaultLocation()); - assertEquals("Should have same number of bundles", pluginPaths.length, urls.size()); - for (int i = 0; i < pluginPaths.length; i++) { - URL url = pluginPaths[i]; - assertTrue("Missing plug-in " + url.toString(), urls.contains(url)); - } - } - finally { - store.setValue(ICoreConstants.TARGET_PLATFORM_REALIZATION, restore); - } - } - - /** - * Tests reading a 3.0.2 install with a mix of classic and OSGi plug-ins. - * - * @throws Exception - */ - public void testClassicPlugins() throws Exception { - // extract the 3.0.2 skeleton - IPath location = extractClassicPlugins(); - - // the new way - ITargetDefinition definition = getTargetService().newTarget(); - IBundleContainer container = getTargetService().newDirectoryContainer(location.toOSString()); - definition.setBundleContainers(new IBundleContainer[]{container}); - Set urls = getAllBundleURLs(definition); - - Preferences store = PDECore.getDefault().getPluginPreferences(); - boolean restore = store.getBoolean(ICoreConstants.TARGET_PLATFORM_REALIZATION); - try { - store.setValue(ICoreConstants.TARGET_PLATFORM_REALIZATION, false); - // the old way - URL[] pluginPaths = PluginPathFinder.getPluginPaths(location.toOSString()); - for (int i = 0; i < pluginPaths.length; i++) { - URL url = pluginPaths[i]; - if (!urls.contains(url)) { - System.err.println(url.toString()); - } - } - assertEquals("Wrong number of bundles", pluginPaths.length, urls.size()); - } - finally { - store.setValue(ICoreConstants.TARGET_PLATFORM_REALIZATION, restore); - } - } - - /** - * Tests identification of source bundles in a 3.0.2 install. - * - * @throws Exception - */ - public void testClassicSourcePlugins() throws Exception { - // extract the 3.0.2 skeleton - IPath location = extractClassicPlugins(); - - // the new way - ITargetDefinition definition = getTargetService().newTarget(); - IBundleContainer container = getTargetService().newDirectoryContainer(location.toOSString()); - definition.setBundleContainers(new IBundleContainer[]{container}); - BundleInfo[] bundles = definition.resolveSourceBundles(null); - assertEquals("Wrong number of source bundles", 3, bundles.length); - Set names = new HashSet(); - for (int i = 0; i < bundles.length; i++) { - names.add(bundles[i].getSymbolicName()); - } - String[] expected = new String[]{"org.eclipse.platform.source", "org.eclipse.jdt.source", "org.eclipse.pde.source"}; - for (int i = 0; i < expected.length; i++) { - assertTrue("Missing source for " + expected[i], names.contains(expected[i])); - } - } - - /** - * Returns the given input stream as a byte array - * @param stream the stream to get as a byte array - * @param length the length to read from the stream or -1 for unknown - * @return the given input stream as a byte array - * @throws IOException - */ - public static byte[] getInputStreamAsByteArray(InputStream stream, int length) throws IOException { - byte[] contents; - if (length == -1) { - contents = new byte[0]; - int contentsLength = 0; - int amountRead = -1; - do { - // read at least 8K - int amountRequested = Math.max(stream.available(), 8192); - // resize contents if needed - if (contentsLength + amountRequested > contents.length) { - System.arraycopy(contents, - 0, - contents = new byte[contentsLength + amountRequested], - 0, - contentsLength); - } - // read as many bytes as possible - amountRead = stream.read(contents, contentsLength, amountRequested); - if (amountRead > 0) { - // remember length of contents - contentsLength += amountRead; - } - } while (amountRead != -1); - // resize contents if necessary - if (contentsLength < contents.length) { - System.arraycopy(contents, 0, contents = new byte[contentsLength], 0, contentsLength); - } - } else { - contents = new byte[length]; - int len = 0; - int readSize = 0; - while ((readSize != -1) && (len != length)) { - // See PR 1FMS89U - // We record first the read size. In this case length is the actual - // read size. - len += readSize; - readSize = stream.read(contents, len, length - len); - } - } - return contents; - } - - /** - * Tests restoration of a handle to target definition in an IFile - * @throws CoreException - */ - public void testWorkspaceTargetHandleMemento() throws CoreException { - ITargetPlatformService service = getTargetService(); - IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path("does/not/exist")); - ITargetHandle handle = service.getTarget(file); - assertFalse("Target should not exist", handle.exists()); - String memento = handle.getMemento(); - assertNotNull("Missing memento", memento); - ITargetHandle handle2 = service.getTarget(memento); - assertEquals("Restore failed", handle, handle2); - IFile file2 = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path("does/not/exist/either")); - ITargetHandle handle3 = service.getTarget(file2); - assertFalse("Should be different targets", handle.equals(handle3)); - } - - /** - * Tests restoration of a handle to target definition in local metadata - * - * @throws CoreException - * @throws InterruptedException - */ - public void testLocalTargetHandleMemento() throws CoreException, InterruptedException { - ITargetPlatformService service = getTargetService(); - ITargetHandle handle = service.newTarget().getHandle(); - assertFalse("Target should not exist", handle.exists()); - String memento = handle.getMemento(); - assertNotNull("Missing memento", memento); - ITargetHandle handle2 = service.getTarget(memento); - assertEquals("Restore failed", handle, handle2); - ITargetHandle handle3 = service.newTarget().getHandle(); - assertFalse("Should be different targets", handle.equals(handle3)); - } - - /** - * Returns the location of the JDT feature in the running host as - * a path in the local file system. - * - * @return path to JDT feature - */ - protected IPath getJdtFeatureLocation() { - IPath path = new Path(TargetPlatform.getDefaultLocation()); - path = path.append("features"); - File dir = path.toFile(); - assertTrue("Missing features directory", dir.exists() && !dir.isFile()); - String[] files = dir.list(); - String location = null; - for (int i = 0; i < files.length; i++) { - if (files[i].startsWith("org.eclipse.jdt_")) { - location = path.append(files[i]).toOSString(); - break; - } - } - assertNotNull("Missing JDT feature", location); - return new Path(location); - } - - /** - * Tests a JDT feature bundle container contains the appropriate bundles - * @throws Exception - */ - public void testFeatureBundleContainer() throws Exception { - IBundleContainer container = getTargetService().newFeatureContainer("${eclipse_home}", "org.eclipse.jdt", null); - BundleInfo[] bundles = container.resolveBundles(null); - - Set expected = new HashSet(); - expected.add("org.eclipse.jdt"); - expected.add("org.eclipse.ant.ui"); - expected.add("org.eclipse.jdt.apt.core"); - expected.add("org.eclipse.jdt.apt.ui"); - expected.add("org.eclipse.jdt.apt.pluggable.core"); - expected.add("org.eclipse.jdt.compiler.apt"); - expected.add("org.eclipse.jdt.compiler.tool"); - expected.add("org.eclipse.jdt.core"); - expected.add("org.eclipse.jdt.core.manipulation"); - expected.add("org.eclipse.jdt.debug.ui"); - expected.add("org.eclipse.jdt.debug"); - expected.add("org.eclipse.jdt.junit"); - expected.add("org.eclipse.jdt.junit.runtime"); - expected.add("org.eclipse.jdt.junit4.runtime"); - expected.add("org.eclipse.jdt.launching"); - expected.add("org.eclipse.jdt.ui"); - expected.add("org.junit"); - expected.add("org.junit4"); - expected.add("org.eclipse.jdt.doc.user"); - if (Platform.getOS() == Platform.OS_MACOSX) { - expected.add("org.eclipse.jdt.launching.macosx"); - } - assertEquals("Wrong number of bundles in JDT feature", expected.size(), bundles.length); - for (int i = 0; i < bundles.length; i++) { - expected.remove(bundles[i].getSymbolicName()); - } - Iterator iterator = expected.iterator(); - while (iterator.hasNext()) { - String name = (String) iterator.next(); - System.err.println("Missing: " + name); - } - assertTrue("Wrong bundles in JDT feature", expected.isEmpty()); - - - // should be no source bundles - bundles = container.resolveSourceBundles(null); - assertEquals("Wrong source bundle count", 0, bundles.length); - } - - /** - * Tests that a target definition based on the JDT feature - * restricted to a subset of bundles contains the right set. - * - * @throws Exception - */ - public void testRestrictedFeatureBundleContainer() throws Exception { - ITargetDefinition definition = getTargetService().newTarget(); - IBundleContainer container = getTargetService().newFeatureContainer("${eclipse_home}", "org.eclipse.jdt", null); - BundleInfo[] restrictions = new BundleInfo[]{ - new BundleInfo("org.eclipse.jdt.launching", null, null, BundleInfo.NO_LEVEL, false), - new BundleInfo("org.eclipse.jdt.debug", null, null, BundleInfo.NO_LEVEL, false) - }; - container.setRestrictions(restrictions); - definition.setBundleContainers(new IBundleContainer[]{container}); - List infos = getAllBundleInfos(definition); - - assertEquals("Wrong number of bundles", 2, infos.size()); - Set set = collectAllSymbolicNames(infos); - for (int i = 0; i < restrictions.length; i++) { - BundleInfo info = restrictions[i]; - set.remove(info.getSymbolicName()); - } - assertEquals("Wrong bundles", 0, set.size()); - - } - - /** - * Tests a JDT source feature bundle container contains the appropriate bundles - * @throws Exception - */ - public void testSourceFeatureBundleContainer() throws Exception { - IBundleContainer container = getTargetService().newFeatureContainer("${eclipse_home}", "org.eclipse.jdt.source", null); - BundleInfo[] bundles = container.resolveSourceBundles(null); - - Set expected = new HashSet(); - expected.add("org.eclipse.jdt.source"); - expected.add("org.eclipse.ant.ui.source"); - expected.add("org.eclipse.jdt.apt.core.source"); - expected.add("org.eclipse.jdt.apt.ui.source"); - expected.add("org.eclipse.jdt.apt.pluggable.core.source"); - expected.add("org.eclipse.jdt.compiler.apt.source"); - expected.add("org.eclipse.jdt.compiler.tool.source"); - expected.add("org.eclipse.jdt.core.source"); - expected.add("org.eclipse.jdt.core.manipulation.source"); - expected.add("org.eclipse.jdt.debug.ui.source"); - expected.add("org.eclipse.jdt.debug.source"); - expected.add("org.eclipse.jdt.junit.source"); - expected.add("org.eclipse.jdt.junit.runtime.source"); - expected.add("org.eclipse.jdt.junit4.runtime.source"); - expected.add("org.eclipse.jdt.launching.source"); - expected.add("org.eclipse.jdt.ui.source"); - expected.add("org.junit.source"); - expected.add("org.junit4.source"); - if (Platform.getOS() == Platform.OS_MACOSX) { - expected.add("org.eclipse.jdt.launching.macosx.source"); - } - for (int i = 0; i < bundles.length; i++) { - expected.remove(bundles[i].getSymbolicName()); - } - Iterator iterator = expected.iterator(); - while (iterator.hasNext()) { - String name = (String) iterator.next(); - System.err.println("Missing: " + name); - } - assertTrue("Wrong bundles in JDT feature", expected.isEmpty()); - - - // should be one doc bundle - bundles = container.resolveBundles(null); - assertEquals("Wrong bundle count", 1, bundles.length); - assertEquals("Missing bundle", "org.eclipse.jdt.doc.isv", bundles[0].getSymbolicName()); - } - - - /** - * Tests setting the target platform to the JDT feature with a specific version. - * - * @throws Exception - */ - public void testSetTargetPlatformToJdtFeature() throws Exception { - try { - IPath location = getJdtFeatureLocation(); - String segment = location.lastSegment(); - int index = segment.indexOf('_'); - assertTrue("Missing version id", index > 0); - String version = segment.substring(index + 1); - ITargetPlatformService targetService = getTargetService(); - IBundleContainer container = targetService.newFeatureContainer("${eclipse_home}", "org.eclipse.jdt", version); - ITargetDefinition target = targetService.newTarget(); - target.setBundleContainers(new IBundleContainer[]{container}); - - setTargetPlatform(target); - - Set expected = new HashSet(); - expected.add("org.eclipse.jdt"); - expected.add("org.eclipse.ant.ui"); - expected.add("org.eclipse.jdt.apt.core"); - expected.add("org.eclipse.jdt.apt.ui"); - expected.add("org.eclipse.jdt.apt.pluggable.core"); - expected.add("org.eclipse.jdt.compiler.apt"); - expected.add("org.eclipse.jdt.compiler.tool"); - expected.add("org.eclipse.jdt.core"); - expected.add("org.eclipse.jdt.core.manipulation"); - expected.add("org.eclipse.jdt.debug.ui"); - expected.add("org.eclipse.jdt.debug"); - expected.add("org.eclipse.jdt.junit"); - expected.add("org.eclipse.jdt.junit.runtime"); - expected.add("org.eclipse.jdt.junit4.runtime"); - expected.add("org.eclipse.jdt.launching"); - expected.add("org.eclipse.jdt.ui"); - expected.add("org.junit"); - expected.add("org.junit4"); - expected.add("org.eclipse.jdt.doc.user"); - if (Platform.getOS() == Platform.OS_MACOSX) { - expected.add("org.eclipse.jdt.launching.macosx"); - } - - // current platform - IPluginModelBase[] models = TargetPlatformHelper.getPDEState().getTargetModels(); - - assertEquals("Wrong number of bundles in JDT feature", expected.size(), models.length); - for (int i = 0; i < models.length; i++) { - expected.remove(models[i].getPluginBase().getId()); - assertTrue(models[i].isEnabled()); - } - Iterator iterator = expected.iterator(); - while (iterator.hasNext()) { - String name = (String) iterator.next(); - System.err.println("Missing: " + name); - } - assertTrue("Wrong bundles in target platform", expected.isEmpty()); - } finally { - resetTargetPlatform(); - } - } - - /** - * Tests setting the target platform to empty. - * @throws CoreException - */ - public void testSetEmptyTargetPlatform() throws CoreException { - try { - setTargetPlatform(null); - - // current platform - IPluginModelBase[] models = TargetPlatformHelper.getPDEState().getTargetModels(); - - assertEquals("Wrong number of bundles in empty target", 0, models.length); - - } finally { - resetTargetPlatform(); - } - } - - /** - * Tests that a complex target definition can be serialized to xml, then deserialized without - * any loss of data. - * - * @throws Exception - */ - public void testPersistComplexDefinition() throws Exception { - ITargetDefinition definitionA = getTargetService().newTarget(); - - definitionA.setName("name"); - definitionA.setDescription("description"); - definitionA.setOS("os"); - definitionA.setWS("ws"); - definitionA.setArch("arch"); - definitionA.setNL("nl"); - definitionA.setProgramArguments("program\nargs"); - definitionA.setVMArguments("vm\nargs"); - definitionA.setJREContainer(JavaRuntime.newDefaultJREContainerPath()); - - BundleInfo[] implicit = new BundleInfo[]{ - new BundleInfo("org.eclipse.jdt.launching", null, null, BundleInfo.NO_LEVEL, false), - new BundleInfo("org.eclipse.jdt.debug", null, null, BundleInfo.NO_LEVEL, false) - }; - definitionA.setImplicitDependencies(implicit); - - // Directory container - IBundleContainer dirContainer = getTargetService().newDirectoryContainer(TargetPlatform.getDefaultLocation() + "/plugins"); - // Profile container with specific config area - IBundleContainer profileContainer = getTargetService().newProfileContainer(TargetPlatform.getDefaultLocation(), new File(Platform.getConfigurationLocation().getURL().getFile()).getAbsolutePath()); - // Feature container with specific version - // TODO Unexpected CoreException when running -// IPath location = getJdtFeatureLocation(); -// String segment = location.lastSegment(); -// int index = segment.indexOf('_'); -// assertTrue("Missing version id", index > 0); -// String version = segment.substring(index + 1); -// IBundleContainer featureContainer = getTargetService().newFeatureContainer("${eclipse_home}", "org.eclipse.jdt", version); - // Profile container restricted to just two bundles - IBundleContainer restrictedProfileContainer = getTargetService().newProfileContainer(TargetPlatform.getDefaultLocation(), null); - BundleInfo[] restrictions = new BundleInfo[]{ - new BundleInfo("org.eclipse.jdt.launching", null, null, BundleInfo.NO_LEVEL, false), - new BundleInfo("org.eclipse.jdt.debug", null, null, BundleInfo.NO_LEVEL, false) - }; - restrictedProfileContainer.setRestrictions(restrictions); - definitionA.setBundleContainers(new IBundleContainer[]{dirContainer, profileContainer, /*featureContainer,*/ restrictedProfileContainer}); - - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - TargetDefinitionPersistenceHelper.persistXML(definitionA, outputStream); - ITargetDefinition definitionB = getTargetService().newTarget(); - ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); - TargetDefinitionPersistenceHelper.initFromXML(definitionB, inputStream); - - assertTargetDefinitionsEqual(definitionA, definitionB); - } - - /** - * Tests that an empty target definition can be serialized to xml, then deserialized without - * any loss of data. - * - * @throws Exception - */ - public void testPersistEmptyDefinition() throws Exception { - ITargetDefinition definitionA = getTargetService().newTarget(); - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - TargetDefinitionPersistenceHelper.persistXML(definitionA, outputStream); - ITargetDefinition definitionB = getTargetService().newTarget(); - ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); - TargetDefinitionPersistenceHelper.initFromXML(definitionB, inputStream); - assertTargetDefinitionsEqual(definitionA, definitionB); - } - - protected void assertTargetDefinitionsEqual(ITargetDefinition targetA, ITargetDefinition targetB) throws CoreException{ - assertEquals(targetA.getName(),targetB.getName()); - assertEquals(targetA.getDescription(),targetB.getDescription()); - assertEquals(targetA.getOS(),targetB.getOS()); - assertEquals(targetA.getWS(),targetB.getWS()); - assertEquals(targetA.getArch(),targetB.getArch()); - assertEquals(targetA.getNL(),targetB.getNL()); - assertEquals(targetA.getProgramArguments(),targetB.getProgramArguments()); - assertEquals(targetA.getVMArguments(),targetB.getVMArguments()); - assertEquals(targetA.getJREContainer(),targetB.getJREContainer()); - - if (targetA.getImplicitDependencies() != null){ - List implicitAList = Arrays.asList(targetA.getImplicitDependencies()); - Set implicitA = collectAllSymbolicNames(implicitAList); - BundleInfo[] implicitB = targetB.getImplicitDependencies(); - assertNotNull("Bundle container's restrictions are missing",implicitB); - for (int i = 0; i < implicitB.length; i++) { - assertTrue("Missing implicit dependency", implicitA.contains(implicitB[i].getSymbolicName())); - } - } - - IBundleContainer[] containersA = targetA.getBundleContainers(); - IBundleContainer[] containersB = targetB.getBundleContainers(); - if (containersA != null){ - assertNotNull("Bundle containers are missing",containersB); - for (int aIndex = 0; aIndex < containersA.length; aIndex++) { - boolean foundMatch = false; - for (int bIndex = 0; bIndex < containersB.length; bIndex++) { - if (containersA[aIndex].getClass().getName().equals(containersB[bIndex].getClass().getName()) - && getResolvedLocation(containersA[aIndex]).equals(getResolvedLocation(containersB[bIndex])) - && containersA[aIndex].resolveBundles(null).length == containersB[bIndex].resolveBundles(null).length){ - - boolean matchingRestrictions = true; - if (containersA[aIndex].getRestrictions() != null){ - List restrictionsA = Arrays.asList(containersA[aIndex].getRestrictions()); - Set restrictionIDs = collectAllSymbolicNames(restrictionsA); - BundleInfo[] restrictionsB = containersB[bIndex].getRestrictions(); - assertNotNull("Bundle container's restrictions are missing",restrictionsB); - for (int restrictB = 0; restrictB < restrictionsB.length; restrictB++) { - if (!restrictionIDs.contains(restrictionsB[restrictB].getSymbolicName())){ - matchingRestrictions = false; - } - } - } - if (matchingRestrictions){ - foundMatch = true; - } - } - } - assertTrue("The target definitions have non matching bundle containers",foundMatch); - } - } - - } - - /** - * Reads a target definition file from the tests/targets/target-files location - * with the given name. Note that ".target" will be appended. - * - * @param name - * @return target definition - * @throws Exception - */ - protected ITargetDefinition readOldTarget(String name) throws Exception { - URL url = MacroPlugin.getBundleContext().getBundle().getEntry("/tests/targets/target-files/" + name + ".target"); - File file = new File(FileLocator.toFileURL(url).getFile()); - ITargetDefinition target = getTargetService().newTarget(); - FileInputStream stream = new FileInputStream(file); - TargetDefinitionPersistenceHelper.initFromXML(target, stream); - stream.close(); - return target; - } - - /** - * Tests that we can de-serialize an old style target definition file (version 3.2) and retrieve the correct - * contents. - * - * @throws Exception - */ - public void testReadOldBasicTargetFile() throws Exception { - ITargetDefinition target = readOldTarget("basic"); - - assertEquals("Wrong name", "Basic", target.getName()); - assertNull(target.getDescription()); - assertNull(target.getArch()); - assertNull(target.getOS()); - assertNull(target.getNL()); - assertNull(target.getWS()); - assertNull(target.getProgramArguments()); - assertNull(target.getVMArguments()); - assertNull(target.getImplicitDependencies()); - assertNull(target.getJREContainer()); - - IBundleContainer[] containers = target.getBundleContainers(); - assertEquals("Wrong number of bundles", 1, containers.length); - assertTrue("Container should be a profile container", containers[0] instanceof ProfileBundleContainer); - assertEquals("Wrong home location", new Path(TargetPlatform.getDefaultLocation()), - new Path(getResolvedLocation(containers[0]))); - } - - /** - * Tests that we can de-serialize an old style target definition file (version 3.2) and retrieve the correct - * contents. - * - * @throws Exception - */ - public void testReadOldBasicDirectoryTargetFile() throws Exception { - ITargetDefinition target = readOldTarget("directory"); - - assertEquals("Wrong name", "Directory", target.getName()); - assertNull(target.getDescription()); - assertNull(target.getArch()); - assertNull(target.getOS()); - assertNull(target.getNL()); - assertNull(target.getWS()); - assertNull(target.getProgramArguments()); - assertNull(target.getVMArguments()); - assertNull(target.getImplicitDependencies()); - assertNull(target.getJREContainer()); - - IBundleContainer[] containers = target.getBundleContainers(); - assertEquals("Wrong number of bundles", 1, containers.length); - assertTrue("Container should be a directory container", containers[0] instanceof DirectoryBundleContainer); - assertEquals("Wrong home location", new Path(TargetPlatform.getDefaultLocation()).append("plugins"), - new Path(getResolvedLocation(containers[0]))); - } - - /** - * Tests that we can de-serialize an old style target definition file (version 3.2) and retrieve the correct - * contents. - * - * @throws Exception - */ - public void testReadOldSpecificTargetFile() throws Exception { - ITargetDefinition target = readOldTarget("specific"); - - assertEquals("Wrong name", "Specific Settings", target.getName()); - assertNull(target.getDescription()); - assertEquals("x86", target.getArch()); - assertEquals("linux", target.getOS()); - assertEquals("en_US", target.getNL()); - assertEquals("gtk", target.getWS()); - assertEquals("pgm1 pgm2", target.getProgramArguments()); - assertEquals("-Dfoo=\"bar\"", target.getVMArguments()); - assertEquals(JavaRuntime.newJREContainerPath(JavaRuntime.getExecutionEnvironmentsManager().getEnvironment("J2SE-1.4")), target.getJREContainer()); - - BundleInfo[] infos = target.getImplicitDependencies(); - assertEquals("Wrong number of implicit dependencies", 2, infos.length); - Set set = new HashSet(); - for (int i = 0; i < infos.length; i++) { - set.add(infos[i].getSymbolicName()); - } - assertTrue("Missing ", set.remove("org.eclipse.jdt.debug")); - assertTrue("Missing ", set.remove("org.eclipse.debug.core")); - assertTrue(set.isEmpty()); - - IBundleContainer[] containers = target.getBundleContainers(); - assertEquals("Wrong number of bundles", 1, containers.length); - assertTrue("Container should be a directory container", containers[0] instanceof DirectoryBundleContainer); - assertEquals("Wrong home location", new Path(TargetPlatform.getDefaultLocation()).append("plugins"), - new Path(getResolvedLocation(containers[0]))); - } - - /** - * Tests that we can de-serialize an old style target definition file (version 3.2) and retrieve the correct - * contents. - * - * @throws Exception - */ - public void testReadOldAdditionLocationsTargetFile() throws Exception { - ITargetDefinition target = readOldTarget("additionalLocations"); - - assertEquals("Wrong name", "Additional Locations", target.getName()); - assertNull(target.getDescription()); - assertNull(target.getArch()); - assertNull(target.getOS()); - assertNull(target.getNL()); - assertNull(target.getWS()); - assertNull(target.getProgramArguments()); - assertNull(target.getVMArguments()); - assertNull(target.getJREContainer()); - assertNull(target.getImplicitDependencies()); - - IBundleContainer[] containers = target.getBundleContainers(); - assertEquals("Wrong number of bundles", 3, containers.length); - assertTrue(containers[0] instanceof ProfileBundleContainer); - assertTrue(containers[1] instanceof DirectoryBundleContainer); - assertTrue(containers[2] instanceof DirectoryBundleContainer); - - assertEquals("Wrong home location", new Path(TargetPlatform.getDefaultLocation()), - new Path(getResolvedLocation(containers[0]))); - - String string = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution("${workspace_loc}"); - assertEquals("Wrong 1st additional location", new Path(string).append("stuff"), - new Path(getResolvedLocation(containers[1]))); - - assertEquals("Wrong 2nd additional location", new Path(TargetPlatform.getDefaultLocation()).append("dropins"), - new Path(getResolvedLocation(containers[2]))); - } - - /** - * Tests that we can de-serialize an old style target definition file (version 3.2) and retrieve the correct - * contents. - * - * @throws Exception - */ - public void testReadOldFeaturesTargetFile() throws Exception { - ITargetDefinition target = readOldTarget("featureLocations"); - - assertEquals("Wrong name", "Features", target.getName()); - assertNull(target.getDescription()); - assertNull(target.getArch()); - assertNull(target.getOS()); - assertNull(target.getNL()); - assertNull(target.getWS()); - assertNull(target.getProgramArguments()); - assertNull(target.getVMArguments()); - assertNull(target.getJREContainer()); - assertNull(target.getImplicitDependencies()); - - IBundleContainer[] containers = target.getBundleContainers(); - assertEquals("Wrong number of bundles", 3, containers.length); - assertTrue(containers[0] instanceof ProfileBundleContainer); - assertTrue(containers[1] instanceof FeatureBundleContainer); - assertTrue(containers[2] instanceof FeatureBundleContainer); - - assertEquals("Wrong home location", new Path(TargetPlatform.getDefaultLocation()), - new Path(getResolvedLocation(containers[0]))); - - assertEquals("Wrong 1st additional location", "org.eclipse.jdt", ((FeatureBundleContainer)containers[1]).getFeatureId()); - assertEquals("Wrong 1st additional location", "org.eclipse.platform", ((FeatureBundleContainer)containers[2]).getFeatureId()); - } - - /** - * Tests that we can de-serialize an old style target definition file (version 3.2) and retrieve the correct - * contents. - * - * @throws Exception - */ - public void testReadOldRestrictionsTargetFile() throws Exception { - ITargetDefinition target = readOldTarget("restrictions"); - - assertEquals("Wrong name", "Restrictions", target.getName()); - assertNull(target.getDescription()); - assertNull(target.getArch()); - assertNull(target.getOS()); - assertNull(target.getNL()); - assertNull(target.getWS()); - assertNull(target.getProgramArguments()); - assertNull(target.getVMArguments()); - assertNull(target.getJREContainer()); - assertNull(target.getImplicitDependencies()); - - BundleInfo[] restrictions = new BundleInfo[]{ - new BundleInfo("org.eclipse.debug.core", null, null, BundleInfo.NO_LEVEL, false), - new BundleInfo("org.eclipse.debug.ui", null, null, BundleInfo.NO_LEVEL, false), - new BundleInfo("org.eclipse.jdt.debug", null, null, BundleInfo.NO_LEVEL, false), - new BundleInfo("org.eclipse.jdt.debug.ui", null, null, BundleInfo.NO_LEVEL, false), - new BundleInfo("org.eclipse.jdt.launching", null, null, BundleInfo.NO_LEVEL, false) - }; - - IBundleContainer[] containers = target.getBundleContainers(); - assertEquals("Wrong number of bundles", 3, containers.length); - assertTrue(containers[0] instanceof ProfileBundleContainer); - assertTrue(containers[1] instanceof FeatureBundleContainer); - assertTrue(containers[2] instanceof DirectoryBundleContainer); - - assertEquals("Wrong home location", new Path(TargetPlatform.getDefaultLocation()), new Path(getResolvedLocation(containers[0]))); - assertEquals("Wrong 1st additional location", "org.eclipse.jdt",((FeatureBundleContainer)containers[1]).getFeatureId()); - assertEquals("Wrong 2nd additional location", new Path(TargetPlatform.getDefaultLocation()).append("dropins"), - new Path(getResolvedLocation(containers[2]))); - - for (int i = 0; i < containers.length; i++) { - IBundleContainer container = containers[i]; - BundleInfo[] actual = container.getRestrictions(); - assertNotNull(actual); - assertEquals("Wrong number of restrictions", restrictions.length, actual.length); - for (int j = 0; j < actual.length; j++) { - assertEquals("Wrong restriction", restrictions[j], actual[j]); - } - } - } - - /** - * Tests resolution of implicit dependencies in a default target platform - * - * @throws Exception - */ - public void testImplicitDependencies() throws Exception { - ITargetDefinition definition = getTargetService().newTarget(); - IBundleContainer container = getTargetService().newProfileContainer(TargetPlatform.getDefaultLocation(), null); - definition.setBundleContainers(new IBundleContainer[]{container}); - BundleInfo[] implicit = new BundleInfo[]{ - new BundleInfo("org.eclipse.jdt.launching", null, null, BundleInfo.NO_LEVEL, false), - new BundleInfo("org.eclipse.jdt.debug", null, null, BundleInfo.NO_LEVEL, false) - }; - definition.setImplicitDependencies(implicit); - BundleInfo[] infos = definition.resolveImplicitDependencies(null); - - assertEquals("Wrong number of bundles", 2, infos.length); - Set set = new HashSet(); - for (int i = 0; i < infos.length; i++) { - set.add(infos[i].getSymbolicName()); - } - for (int i = 0; i < implicit.length; i++) { - BundleInfo info = implicit[i]; - set.remove(info.getSymbolicName()); - } - assertEquals("Wrong bundles", 0, set.size()); - - } - -} +/******************************************************************************* + * Copyright (c) 2008, 2009 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.ui.tests.target; + +import org.eclipse.pde.internal.core.target.impl.TargetDefinition; + +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.pde.internal.core.target.impl.AbstractBundleContainer; + +import org.eclipse.pde.internal.core.target.impl.ProfileBundleContainer; + +import org.eclipse.pde.internal.core.target.impl.FeatureBundleContainer; + +import java.io.*; +import java.net.URL; +import java.util.*; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import junit.framework.TestCase; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.*; +import org.eclipse.core.variables.VariablesPlugin; +import org.eclipse.equinox.internal.provisional.frameworkadmin.BundleInfo; +import org.eclipse.jdt.launching.JavaRuntime; +import org.eclipse.pde.core.plugin.IPluginModelBase; +import org.eclipse.pde.core.plugin.TargetPlatform; +import org.eclipse.pde.internal.core.*; +import org.eclipse.pde.internal.core.target.impl.DirectoryBundleContainer; +import org.eclipse.pde.internal.core.target.impl.TargetDefinitionPersistenceHelper; +import org.eclipse.pde.internal.core.target.provisional.*; +import org.eclipse.pde.internal.ui.tests.macro.MacroPlugin; +import org.osgi.framework.ServiceReference; + +/** + * Tests for target definitions. + * + * @since 3.5 + */ +public class TargetDefinitionTests extends TestCase { + + /** + * Retrieves all bundles (source and code) in the given target definition + * returning them as a set of URLs. + * + * @param target target definition + * @return all bundle URLs + */ + protected Set getAllBundleURLs(ITargetDefinition target) throws Exception { + BundleInfo[] code = target.resolveBundles(null); + BundleInfo[] source = target.resolveSourceBundles(null); + Set urls = new HashSet(code.length + source.length); + for (int i = 0; i < code.length; i++) { + urls.add(new File(code[i].getLocation()).toURL()); + } + for (int i = 0; i < source.length; i++) { + urls.add(new File(source[i].getLocation()).toURL()); + } + return urls; + } + + /** + * Retrieves all bundles (source and code) in the given target definition + * returning them as a list of BundleInfos. + * + * @param target target definition + * @return all BundleInfos + */ + protected List getAllBundleInfos(ITargetDefinition target) throws Exception { + BundleInfo[] code = target.resolveBundles(null); + BundleInfo[] source = target.resolveSourceBundles(null); + List list = new ArrayList(code.length + source.length); + for (int i = 0; i < code.length; i++) { + list.add(code[i]); + } + for (int i = 0; i < source.length; i++) { + list.add(source[i]); + } + return list; + } + + /** + * Collects all bundle symbolic names into a set. + * + * @param infos bundles + * @return bundle symbolic names + */ + protected Set collectAllSymbolicNames(List infos) { + Set set = new HashSet(infos.size()); + Iterator iterator = infos.iterator(); + while (iterator.hasNext()) { + BundleInfo info = (BundleInfo) iterator.next(); + set.add(info.getSymbolicName()); + } + return set; + } + + /** + * Returns the resolved location of the specified bundle container. + * + * @param container bundle container + * @return resolved location + * @throws CoreException + */ + protected String getResolvedLocation(IBundleContainer container) throws CoreException { + return ((AbstractBundleContainer)container).getLocation(true); + } + + /** + * Extracts the classic plug-ins archive, if not already done, and returns a path to the + * root directory containing the plug-ins. + * + * @return path to the plug-ins directory + * @throws Exception + */ + protected IPath extractClassicPlugins() throws Exception { + // extract the 3.0.2 skeleton + IPath stateLocation = MacroPlugin.getDefault().getStateLocation(); + IPath location = stateLocation.append("classic-plugins"); + if (location.toFile().exists()) { + return location; + } + URL zipURL = MacroPlugin.getBundleContext().getBundle().getEntry("/tests/targets/classic-plugins.zip"); + Path zipPath = new Path(new File(FileLocator.toFileURL(zipURL).getFile()).getAbsolutePath()); + ZipFile zipFile = new ZipFile(zipPath.toFile()); + Enumeration entries = zipFile.entries(); + while (entries.hasMoreElements()) { + ZipEntry entry = (ZipEntry) entries.nextElement(); + if (!entry.isDirectory()) { + IPath entryPath = stateLocation.append(entry.getName()); + File dir = entryPath.removeLastSegments(1).toFile(); + dir.mkdirs(); + File file = entryPath.toFile(); + file.createNewFile(); + InputStream inputStream = new BufferedInputStream(zipFile.getInputStream(entry)); + byte[] bytes = getInputStreamAsByteArray(inputStream, -1); + inputStream.close(); + BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(file)); + outputStream.write(bytes); + outputStream.close(); + } + } + zipFile.close(); + return location; + } + + /** + * Returns the target platform service or null if none + * + * @return target platform service + */ + protected ITargetPlatformService getTargetService() { + ServiceReference reference = MacroPlugin.getBundleContext().getServiceReference(ITargetPlatformService.class.getName()); + assertNotNull("Missing target platform service", reference); + if (reference == null) + return null; + return (ITargetPlatformService) MacroPlugin.getBundleContext().getService(reference); + } + + /** + * Returns a default target platform that takes target weaving into account + * if in a second instance of Eclipse. This allows the target platform to be + * reset after changing it in a test. + * + * @return default settings for target platform + */ + protected ITargetDefinition getDefaultTargetPlatorm() { + ITargetDefinition definition = getTargetService().newTarget(); + IBundleContainer container = getTargetService().newProfileContainer(TargetPlatform.getDefaultLocation(), + new File(Platform.getConfigurationLocation().getURL().getFile()).getAbsolutePath()); + definition.setBundleContainers(new IBundleContainer[]{container}); + return definition; + } + + /** + * Used to reset the target platform to original settings after a test that changes + * the target platform. + * @throws CoreException + */ + protected void resetTargetPlatform() throws CoreException { + ITargetDefinition definition = getDefaultTargetPlatorm(); + setTargetPlatform(definition); + } + + /** + * Sets the target platform based on the given definition. + * + * @param target target definition or null + * @throws CoreException + */ + protected void setTargetPlatform(ITargetDefinition target) throws CoreException { + LoadTargetDefinitionJob job = new LoadTargetDefinitionJob(target); + job.schedule(); + try { + job.join(); + } catch (InterruptedException e) { + assertFalse("Target platform reset interrupted", true); + } + ITargetHandle handle = null; + if (target != null) { + handle = target.getHandle(); + } + assertEquals("Wrong target platform handle preference setting", handle, getTargetService().getWorkspaceTargetHandle()); + } + + /** + * Tests that resetting the target platform should work OK (i.e. is equivalent to the + * models in the default target platform). + * + * @throws CoreException + */ + public void testResetTargetPlatform() throws Exception { + ITargetDefinition definition = getDefaultTargetPlatorm(); + Set urls = getAllBundleURLs(definition); + + // current platform + IPluginModelBase[] models = TargetPlatformHelper.getPDEState().getTargetModels(); + + // should be equivalent + assertEquals("Should have same number of bundles", urls.size(), models.length); + for (int i = 0; i < models.length; i++) { + String location = models[i].getInstallLocation(); + assertTrue("Missing plug-in " + location, urls.contains(new File(location).toURL())); + } + } + + /** + * Tests that a target definition equivalent to the default target platform + * contains the same bundles as the default target platform (this is an + * explicit location with no target weaving). + * + * @throws Exception + */ + public void testDefaultTargetPlatform() throws Exception { + // the new way + ITargetDefinition definition = getTargetService().newTarget(); + IBundleContainer container = getTargetService().newProfileContainer(TargetPlatform.getDefaultLocation(), null); + definition.setBundleContainers(new IBundleContainer[]{container}); + Set urls = getAllBundleURLs(definition); + + // the old way + IPath location = new Path(TargetPlatform.getDefaultLocation()); + URL[] pluginPaths = P2Utils.readBundlesTxt(location.toOSString(), location.append("configuration").toFile().toURL()); + assertEquals("Should have same number of bundles", pluginPaths.length, urls.size()); + for (int i = 0; i < pluginPaths.length; i++) { + URL url = pluginPaths[i]; + assertTrue("Missing plug-in " + url.toString(), urls.contains(url)); + } + + } + + /** + * Tests that a target definition based on the default target platform + * restricted to a subset of bundles contains the right set. + * + * @throws Exception + */ + public void testRestrictedDefaultTargetPlatform() throws Exception { + ITargetDefinition definition = getTargetService().newTarget(); + IBundleContainer container = getTargetService().newProfileContainer(TargetPlatform.getDefaultLocation(), null); + BundleInfo[] restrictions = new BundleInfo[]{ + new BundleInfo("org.eclipse.jdt.launching", null, null, BundleInfo.NO_LEVEL, false), + new BundleInfo("org.eclipse.jdt.debug", null, null, BundleInfo.NO_LEVEL, false) + }; + container.setRestrictions(restrictions); + definition.setBundleContainers(new IBundleContainer[]{container}); + List infos = getAllBundleInfos(definition); + + assertEquals("Wrong number of bundles", 2, infos.size()); + Set set = collectAllSymbolicNames(infos); + for (int i = 0; i < restrictions.length; i++) { + BundleInfo info = restrictions[i]; + set.remove(info.getSymbolicName()); + } + assertEquals("Wrong bundles", 0, set.size()); + + } + + /** + * Tests that a target definition based on the default target platform + * restricted to a subset of bundle versions contains the right set. + * + * @throws Exception + */ + public void testVersionRestrictedDefaultTargetPlatform() throws Exception { + ITargetDefinition definition = getTargetService().newTarget(); + IBundleContainer container = getTargetService().newProfileContainer(TargetPlatform.getDefaultLocation(), null); + definition.setBundleContainers(new IBundleContainer[]{container}); + List infos = getAllBundleInfos(definition); + // find right versions + String v1 = null; + String v2 = null; + Iterator iterator = infos.iterator(); + while (iterator.hasNext() && (v2 == null || v1 == null)) { + BundleInfo info = (BundleInfo) iterator.next(); + if (info.getSymbolicName().equals("org.eclipse.jdt.launching")) { + v1 = info.getVersion(); + } else if (info.getSymbolicName().equals("org.eclipse.jdt.debug")) { + v2 = info.getVersion(); + } + } + assertNotNull(v1); + assertNotNull(v2); + + BundleInfo[] restrictions = new BundleInfo[]{ + new BundleInfo("org.eclipse.jdt.launching", v1, null, BundleInfo.NO_LEVEL, false), + new BundleInfo("org.eclipse.jdt.debug", v2, null, BundleInfo.NO_LEVEL, false) + }; + container.setRestrictions(restrictions); + infos = getAllBundleInfos(definition); + + assertEquals("Wrong number of bundles", 2, infos.size()); + iterator = infos.iterator(); + while (iterator.hasNext()) { + BundleInfo info = (BundleInfo) iterator.next(); + if (info.getSymbolicName().equals("org.eclipse.jdt.launching")) { + assertEquals(v1, info.getVersion()); + } else if (info.getSymbolicName().equals("org.eclipse.jdt.debug")) { + assertEquals(v2, info.getVersion()); + } + } + } + + /** + * Tests that a target definition based on the default target platform + * restricted to a subset of bundles contains the right set. In this case + * empty, since the versions specified are bogus. + * + * @throws Exception + */ + public void testMissingVersionRestrictedDefaultTargetPlatform() throws Exception { + ITargetDefinition definition = getTargetService().newTarget(); + IBundleContainer container = getTargetService().newProfileContainer(TargetPlatform.getDefaultLocation(), null); + BundleInfo[] restrictions = new BundleInfo[]{ + new BundleInfo("org.eclipse.jdt.launching", "xyz", null, BundleInfo.NO_LEVEL, false), + new BundleInfo("org.eclipse.jdt.debug", "abc", null, BundleInfo.NO_LEVEL, false) + }; + container.setRestrictions(restrictions); + definition.setBundleContainers(new IBundleContainer[]{container}); + List infos = getAllBundleInfos(definition); + + assertEquals("Wrong number of bundles", 0, infos.size()); + } + + /** + * Tests that a target definition equivalent to the default target platform + * contains the same bundles as the default target platform (this is an + * explicit location with no target weaving), when created with a variable + * referencing ${eclipse_home} + * + * @throws Exception + */ + public void testEclipseHomeTargetPlatform() throws Exception { + // the new way + ITargetDefinition definition = getTargetService().newTarget(); + IBundleContainer container = getTargetService().newProfileContainer("${eclipse_home}", null); + definition.setBundleContainers(new IBundleContainer[]{container}); + Set urls = getAllBundleURLs(definition); + + // the old way + IPath location = new Path(TargetPlatform.getDefaultLocation()); + URL[] pluginPaths = P2Utils.readBundlesTxt(location.toOSString(), location.append("configuration").toFile().toURL()); + assertEquals("Should have same number of bundles", pluginPaths.length, urls.size()); + for (int i = 0; i < pluginPaths.length; i++) { + URL url = pluginPaths[i]; + assertTrue("Missing plug-in " + url.toString(), urls.contains(url)); + } + + } + + /** + * Tests that a target definition equivalent to the default target platform + * contains the same bundles as the default target platform (this is an + * explicit location with no target weaving), when created with a variable + * referencing ${eclipse_home}. + * + * @throws Exception + */ + public void testEclipseHomeTargetPlatformAndConfigurationArea() throws Exception { + // the new way + ITargetDefinition definition = getTargetService().newTarget(); + IBundleContainer container = getTargetService().newProfileContainer("${eclipse_home}", "${eclipse_home}/configuration"); + definition.setBundleContainers(new IBundleContainer[]{container}); + Set urls = getAllBundleURLs(definition); + + // the old way + IPath location = new Path(TargetPlatform.getDefaultLocation()); + URL[] pluginPaths = P2Utils.readBundlesTxt(location.toOSString(), location.append("configuration").toFile().toURL()); + assertEquals("Should have same number of bundles", pluginPaths.length, urls.size()); + for (int i = 0; i < pluginPaths.length; i++) { + URL url = pluginPaths[i]; + assertTrue("Missing plug-in " + url.toString(), urls.contains(url)); + } + + } + + /** + * Tests that a target definition equivalent to the default target platform + * contains the same bundles as the default target platform using the + * platform's configuration location (which will do target weaving). This + * is really only tested when run as a JUnit plug-in test suite from + * within Eclipse. + * + * @throws Exception + */ + public void testWovenTargetPlatform() throws Exception { + // the new way + ITargetDefinition definition = getTargetService().newTarget(); + IBundleContainer container = getTargetService().newProfileContainer(TargetPlatform.getDefaultLocation(), + new File(Platform.getConfigurationLocation().getURL().getFile()).getAbsolutePath()); + definition.setBundleContainers(new IBundleContainer[]{container}); + Set urls = getAllBundleURLs(definition); + + // the old way + URL[] pluginPaths = PluginPathFinder.getPluginPaths(TargetPlatform.getDefaultLocation()); + assertEquals("Should have same number of bundles", pluginPaths.length, urls.size()); + for (int i = 0; i < pluginPaths.length; i++) { + URL url = pluginPaths[i]; + assertTrue("Missing plug-in " + url.toString(), urls.contains(url)); + } + + } + + /** + * Tests that a bundle directory container is equivalent to scanning locations. + * + * @throws Exception + */ + public void testDirectoryBundleContainer() throws Exception { + // the new way + ITargetDefinition definition = getTargetService().newTarget(); + IBundleContainer container = getTargetService().newDirectoryContainer(TargetPlatform.getDefaultLocation() + "/plugins"); + definition.setBundleContainers(new IBundleContainer[]{container}); + Set urls = getAllBundleURLs(definition); + + Preferences store = PDECore.getDefault().getPluginPreferences(); + boolean restore = store.getBoolean(ICoreConstants.TARGET_PLATFORM_REALIZATION); + try { + store.setValue(ICoreConstants.TARGET_PLATFORM_REALIZATION, false); + // the old way + URL[] pluginPaths = PluginPathFinder.getPluginPaths(TargetPlatform.getDefaultLocation()); + assertEquals("Should have same number of bundles", pluginPaths.length, urls.size()); + for (int i = 0; i < pluginPaths.length; i++) { + URL url = pluginPaths[i]; + assertTrue("Missing plug-in " + url.toString(), urls.contains(url)); + } + } + finally { + store.setValue(ICoreConstants.TARGET_PLATFORM_REALIZATION, restore); + } + } + + /** + * Tests that a bundle directory container is equivalent to scanning locations + * when it uses a variable to specify its location. + * + * @throws Exception + */ + public void testVariableDirectoryBundleContainer() throws Exception { + // the new way + ITargetDefinition definition = getTargetService().newTarget(); + IBundleContainer container = getTargetService().newDirectoryContainer("${eclipse_home}/plugins"); + definition.setBundleContainers(new IBundleContainer[]{container}); + Set urls = getAllBundleURLs(definition); + + Preferences store = PDECore.getDefault().getPluginPreferences(); + boolean restore = store.getBoolean(ICoreConstants.TARGET_PLATFORM_REALIZATION); + try { + store.setValue(ICoreConstants.TARGET_PLATFORM_REALIZATION, false); + // the old way + URL[] pluginPaths = PluginPathFinder.getPluginPaths(TargetPlatform.getDefaultLocation()); + assertEquals("Should have same number of bundles", pluginPaths.length, urls.size()); + for (int i = 0; i < pluginPaths.length; i++) { + URL url = pluginPaths[i]; + assertTrue("Missing plug-in " + url.toString(), urls.contains(url)); + } + } + finally { + store.setValue(ICoreConstants.TARGET_PLATFORM_REALIZATION, restore); + } + } + + /** + * Tests reading a 3.0.2 install with a mix of classic and OSGi plug-ins. + * + * @throws Exception + */ + public void testClassicPlugins() throws Exception { + // extract the 3.0.2 skeleton + IPath location = extractClassicPlugins(); + + // the new way + ITargetDefinition definition = getTargetService().newTarget(); + IBundleContainer container = getTargetService().newDirectoryContainer(location.toOSString()); + definition.setBundleContainers(new IBundleContainer[]{container}); + Set urls = getAllBundleURLs(definition); + + Preferences store = PDECore.getDefault().getPluginPreferences(); + boolean restore = store.getBoolean(ICoreConstants.TARGET_PLATFORM_REALIZATION); + try { + store.setValue(ICoreConstants.TARGET_PLATFORM_REALIZATION, false); + // the old way + URL[] pluginPaths = PluginPathFinder.getPluginPaths(location.toOSString()); + for (int i = 0; i < pluginPaths.length; i++) { + URL url = pluginPaths[i]; + if (!urls.contains(url)) { + System.err.println(url.toString()); + } + } + assertEquals("Wrong number of bundles", pluginPaths.length, urls.size()); + } + finally { + store.setValue(ICoreConstants.TARGET_PLATFORM_REALIZATION, restore); + } + } + + /** + * Tests identification of source bundles in a 3.0.2 install. + * + * @throws Exception + */ + public void testClassicSourcePlugins() throws Exception { + // extract the 3.0.2 skeleton + IPath location = extractClassicPlugins(); + + // the new way + ITargetDefinition definition = getTargetService().newTarget(); + IBundleContainer container = getTargetService().newDirectoryContainer(location.toOSString()); + definition.setBundleContainers(new IBundleContainer[]{container}); + BundleInfo[] bundles = definition.resolveSourceBundles(null); + assertEquals("Wrong number of source bundles", 3, bundles.length); + Set names = new HashSet(); + for (int i = 0; i < bundles.length; i++) { + names.add(bundles[i].getSymbolicName()); + } + String[] expected = new String[]{"org.eclipse.platform.source", "org.eclipse.jdt.source", "org.eclipse.pde.source"}; + for (int i = 0; i < expected.length; i++) { + assertTrue("Missing source for " + expected[i], names.contains(expected[i])); + } + } + + /** + * Returns the given input stream as a byte array + * @param stream the stream to get as a byte array + * @param length the length to read from the stream or -1 for unknown + * @return the given input stream as a byte array + * @throws IOException + */ + public static byte[] getInputStreamAsByteArray(InputStream stream, int length) throws IOException { + byte[] contents; + if (length == -1) { + contents = new byte[0]; + int contentsLength = 0; + int amountRead = -1; + do { + // read at least 8K + int amountRequested = Math.max(stream.available(), 8192); + // resize contents if needed + if (contentsLength + amountRequested > contents.length) { + System.arraycopy(contents, + 0, + contents = new byte[contentsLength + amountRequested], + 0, + contentsLength); + } + // read as many bytes as possible + amountRead = stream.read(contents, contentsLength, amountRequested); + if (amountRead > 0) { + // remember length of contents + contentsLength += amountRead; + } + } while (amountRead != -1); + // resize contents if necessary + if (contentsLength < contents.length) { + System.arraycopy(contents, 0, contents = new byte[contentsLength], 0, contentsLength); + } + } else { + contents = new byte[length]; + int len = 0; + int readSize = 0; + while ((readSize != -1) && (len != length)) { + // See PR 1FMS89U + // We record first the read size. In this case length is the actual + // read size. + len += readSize; + readSize = stream.read(contents, len, length - len); + } + } + return contents; + } + + /** + * Tests restoration of a handle to target definition in an IFile + * @throws CoreException + */ + public void testWorkspaceTargetHandleMemento() throws CoreException { + ITargetPlatformService service = getTargetService(); + IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path("does/not/exist")); + ITargetHandle handle = service.getTarget(file); + assertFalse("Target should not exist", handle.exists()); + String memento = handle.getMemento(); + assertNotNull("Missing memento", memento); + ITargetHandle handle2 = service.getTarget(memento); + assertEquals("Restore failed", handle, handle2); + IFile file2 = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path("does/not/exist/either")); + ITargetHandle handle3 = service.getTarget(file2); + assertFalse("Should be different targets", handle.equals(handle3)); + } + + /** + * Tests restoration of a handle to target definition in local metadata + * + * @throws CoreException + * @throws InterruptedException + */ + public void testLocalTargetHandleMemento() throws CoreException, InterruptedException { + ITargetPlatformService service = getTargetService(); + ITargetHandle handle = service.newTarget().getHandle(); + assertFalse("Target should not exist", handle.exists()); + String memento = handle.getMemento(); + assertNotNull("Missing memento", memento); + ITargetHandle handle2 = service.getTarget(memento); + assertEquals("Restore failed", handle, handle2); + ITargetHandle handle3 = service.newTarget().getHandle(); + assertFalse("Should be different targets", handle.equals(handle3)); + } + + /** + * Returns the location of the JDT feature in the running host as + * a path in the local file system. + * + * @return path to JDT feature + */ + protected IPath getJdtFeatureLocation() { + IPath path = new Path(TargetPlatform.getDefaultLocation()); + path = path.append("features"); + File dir = path.toFile(); + assertTrue("Missing features directory", dir.exists() && !dir.isFile()); + String[] files = dir.list(); + String location = null; + for (int i = 0; i < files.length; i++) { + if (files[i].startsWith("org.eclipse.jdt_")) { + location = path.append(files[i]).toOSString(); + break; + } + } + assertNotNull("Missing JDT feature", location); + return new Path(location); + } + + /** + * Tests a JDT feature bundle container contains the appropriate bundles + * @throws Exception + */ + public void testFeatureBundleContainer() throws Exception { + IBundleContainer container = getTargetService().newFeatureContainer("${eclipse_home}", "org.eclipse.jdt", null); + BundleInfo[] bundles = container.resolveBundles(null); + + Set expected = new HashSet(); + expected.add("org.eclipse.jdt"); + expected.add("org.eclipse.ant.ui"); + expected.add("org.eclipse.jdt.apt.core"); + expected.add("org.eclipse.jdt.apt.ui"); + expected.add("org.eclipse.jdt.apt.pluggable.core"); + expected.add("org.eclipse.jdt.compiler.apt"); + expected.add("org.eclipse.jdt.compiler.tool"); + expected.add("org.eclipse.jdt.core"); + expected.add("org.eclipse.jdt.core.manipulation"); + expected.add("org.eclipse.jdt.debug.ui"); + expected.add("org.eclipse.jdt.debug"); + expected.add("org.eclipse.jdt.junit"); + expected.add("org.eclipse.jdt.junit.runtime"); + expected.add("org.eclipse.jdt.junit4.runtime"); + expected.add("org.eclipse.jdt.launching"); + expected.add("org.eclipse.jdt.ui"); + expected.add("org.junit"); + expected.add("org.junit4"); + expected.add("org.eclipse.jdt.doc.user"); + if (Platform.getOS() == Platform.OS_MACOSX) { + expected.add("org.eclipse.jdt.launching.macosx"); + } + assertEquals("Wrong number of bundles in JDT feature", expected.size(), bundles.length); + for (int i = 0; i < bundles.length; i++) { + expected.remove(bundles[i].getSymbolicName()); + } + Iterator iterator = expected.iterator(); + while (iterator.hasNext()) { + String name = (String) iterator.next(); + System.err.println("Missing: " + name); + } + assertTrue("Wrong bundles in JDT feature", expected.isEmpty()); + + + // should be no source bundles + bundles = container.resolveSourceBundles(null); + assertEquals("Wrong source bundle count", 0, bundles.length); + } + + /** + * Tests that a target definition based on the JDT feature + * restricted to a subset of bundles contains the right set. + * + * @throws Exception + */ + public void testRestrictedFeatureBundleContainer() throws Exception { + ITargetDefinition definition = getTargetService().newTarget(); + IBundleContainer container = getTargetService().newFeatureContainer("${eclipse_home}", "org.eclipse.jdt", null); + BundleInfo[] restrictions = new BundleInfo[]{ + new BundleInfo("org.eclipse.jdt.launching", null, null, BundleInfo.NO_LEVEL, false), + new BundleInfo("org.eclipse.jdt.debug", null, null, BundleInfo.NO_LEVEL, false) + }; + container.setRestrictions(restrictions); + definition.setBundleContainers(new IBundleContainer[]{container}); + List infos = getAllBundleInfos(definition); + + assertEquals("Wrong number of bundles", 2, infos.size()); + Set set = collectAllSymbolicNames(infos); + for (int i = 0; i < restrictions.length; i++) { + BundleInfo info = restrictions[i]; + set.remove(info.getSymbolicName()); + } + assertEquals("Wrong bundles", 0, set.size()); + + } + + /** + * Tests a JDT source feature bundle container contains the appropriate bundles + * @throws Exception + */ + public void testSourceFeatureBundleContainer() throws Exception { + IBundleContainer container = getTargetService().newFeatureContainer("${eclipse_home}", "org.eclipse.jdt.source", null); + BundleInfo[] bundles = container.resolveSourceBundles(null); + + Set expected = new HashSet(); + expected.add("org.eclipse.jdt.source"); + expected.add("org.eclipse.ant.ui.source"); + expected.add("org.eclipse.jdt.apt.core.source"); + expected.add("org.eclipse.jdt.apt.ui.source"); + expected.add("org.eclipse.jdt.apt.pluggable.core.source"); + expected.add("org.eclipse.jdt.compiler.apt.source"); + expected.add("org.eclipse.jdt.compiler.tool.source"); + expected.add("org.eclipse.jdt.core.source"); + expected.add("org.eclipse.jdt.core.manipulation.source"); + expected.add("org.eclipse.jdt.debug.ui.source"); + expected.add("org.eclipse.jdt.debug.source"); + expected.add("org.eclipse.jdt.junit.source"); + expected.add("org.eclipse.jdt.junit.runtime.source"); + expected.add("org.eclipse.jdt.junit4.runtime.source"); + expected.add("org.eclipse.jdt.launching.source"); + expected.add("org.eclipse.jdt.ui.source"); + expected.add("org.junit.source"); + expected.add("org.junit4.source"); + if (Platform.getOS() == Platform.OS_MACOSX) { + expected.add("org.eclipse.jdt.launching.macosx.source"); + } + for (int i = 0; i < bundles.length; i++) { + expected.remove(bundles[i].getSymbolicName()); + } + Iterator iterator = expected.iterator(); + while (iterator.hasNext()) { + String name = (String) iterator.next(); + System.err.println("Missing: " + name); + } + assertTrue("Wrong bundles in JDT feature", expected.isEmpty()); + + + // should be one doc bundle + bundles = container.resolveBundles(null); + assertEquals("Wrong bundle count", 1, bundles.length); + assertEquals("Missing bundle", "org.eclipse.jdt.doc.isv", bundles[0].getSymbolicName()); + } + + + /** + * Tests setting the target platform to the JDT feature with a specific version. + * + * @throws Exception + */ + public void testSetTargetPlatformToJdtFeature() throws Exception { + try { + IPath location = getJdtFeatureLocation(); + String segment = location.lastSegment(); + int index = segment.indexOf('_'); + assertTrue("Missing version id", index > 0); + String version = segment.substring(index + 1); + ITargetPlatformService targetService = getTargetService(); + IBundleContainer container = targetService.newFeatureContainer("${eclipse_home}", "org.eclipse.jdt", version); + ITargetDefinition target = targetService.newTarget(); + target.setBundleContainers(new IBundleContainer[]{container}); + + setTargetPlatform(target); + + Set expected = new HashSet(); + expected.add("org.eclipse.jdt"); + expected.add("org.eclipse.ant.ui"); + expected.add("org.eclipse.jdt.apt.core"); + expected.add("org.eclipse.jdt.apt.ui"); + expected.add("org.eclipse.jdt.apt.pluggable.core"); + expected.add("org.eclipse.jdt.compiler.apt"); + expected.add("org.eclipse.jdt.compiler.tool"); + expected.add("org.eclipse.jdt.core"); + expected.add("org.eclipse.jdt.core.manipulation"); + expected.add("org.eclipse.jdt.debug.ui"); + expected.add("org.eclipse.jdt.debug"); + expected.add("org.eclipse.jdt.junit"); + expected.add("org.eclipse.jdt.junit.runtime"); + expected.add("org.eclipse.jdt.junit4.runtime"); + expected.add("org.eclipse.jdt.launching"); + expected.add("org.eclipse.jdt.ui"); + expected.add("org.junit"); + expected.add("org.junit4"); + expected.add("org.eclipse.jdt.doc.user"); + if (Platform.getOS() == Platform.OS_MACOSX) { + expected.add("org.eclipse.jdt.launching.macosx"); + } + + // current platform + IPluginModelBase[] models = TargetPlatformHelper.getPDEState().getTargetModels(); + + assertEquals("Wrong number of bundles in JDT feature", expected.size(), models.length); + for (int i = 0; i < models.length; i++) { + expected.remove(models[i].getPluginBase().getId()); + assertTrue(models[i].isEnabled()); + } + Iterator iterator = expected.iterator(); + while (iterator.hasNext()) { + String name = (String) iterator.next(); + System.err.println("Missing: " + name); + } + assertTrue("Wrong bundles in target platform", expected.isEmpty()); + } finally { + resetTargetPlatform(); + } + } + + /** + * Tests setting the target platform to empty. + * @throws CoreException + */ + public void testSetEmptyTargetPlatform() throws CoreException { + try { + setTargetPlatform(null); + + // current platform + IPluginModelBase[] models = TargetPlatformHelper.getPDEState().getTargetModels(); + + assertEquals("Wrong number of bundles in empty target", 0, models.length); + + } finally { + resetTargetPlatform(); + } + } + + /** + * Tests that a complex target definition can be serialized to xml, then deserialized without + * any loss of data. + * + * @throws Exception + */ + public void testPersistComplexDefinition() throws Exception { + ITargetDefinition definitionA = getTargetService().newTarget(); + + definitionA.setName("name"); + definitionA.setDescription("description"); + definitionA.setOS("os"); + definitionA.setWS("ws"); + definitionA.setArch("arch"); + definitionA.setNL("nl"); + definitionA.setProgramArguments("program\nargs"); + definitionA.setVMArguments("vm\nargs"); + definitionA.setJREContainer(JavaRuntime.newDefaultJREContainerPath()); + + BundleInfo[] implicit = new BundleInfo[]{ + new BundleInfo("org.eclipse.jdt.launching", null, null, BundleInfo.NO_LEVEL, false), + new BundleInfo("org.eclipse.jdt.debug", null, null, BundleInfo.NO_LEVEL, false) + }; + definitionA.setImplicitDependencies(implicit); + + // Directory container + IBundleContainer dirContainer = getTargetService().newDirectoryContainer(TargetPlatform.getDefaultLocation() + "/plugins"); + // Profile container with specific config area + IBundleContainer profileContainer = getTargetService().newProfileContainer(TargetPlatform.getDefaultLocation(), new File(Platform.getConfigurationLocation().getURL().getFile()).getAbsolutePath()); + // Feature container with specific version + // TODO Unexpected CoreException when running +// IPath location = getJdtFeatureLocation(); +// String segment = location.lastSegment(); +// int index = segment.indexOf('_'); +// assertTrue("Missing version id", index > 0); +// String version = segment.substring(index + 1); +// IBundleContainer featureContainer = getTargetService().newFeatureContainer("${eclipse_home}", "org.eclipse.jdt", version); + // Profile container restricted to just two bundles + IBundleContainer restrictedProfileContainer = getTargetService().newProfileContainer(TargetPlatform.getDefaultLocation(), null); + BundleInfo[] restrictions = new BundleInfo[]{ + new BundleInfo("org.eclipse.jdt.launching", null, null, BundleInfo.NO_LEVEL, false), + new BundleInfo("org.eclipse.jdt.debug", null, null, BundleInfo.NO_LEVEL, false) + }; + restrictedProfileContainer.setRestrictions(restrictions); + definitionA.setBundleContainers(new IBundleContainer[]{dirContainer, profileContainer, /*featureContainer,*/ restrictedProfileContainer}); + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + TargetDefinitionPersistenceHelper.persistXML(definitionA, outputStream); + ITargetDefinition definitionB = getTargetService().newTarget(); + ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); + TargetDefinitionPersistenceHelper.initFromXML(definitionB, inputStream); + + assertTargetDefinitionsEqual(definitionA, definitionB); + } + + /** + * Tests that an empty target definition can be serialized to xml, then deserialized without + * any loss of data. + * + * @throws Exception + */ + public void testPersistEmptyDefinition() throws Exception { + ITargetDefinition definitionA = getTargetService().newTarget(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + TargetDefinitionPersistenceHelper.persistXML(definitionA, outputStream); + ITargetDefinition definitionB = getTargetService().newTarget(); + ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); + TargetDefinitionPersistenceHelper.initFromXML(definitionB, inputStream); + assertTargetDefinitionsEqual(definitionA, definitionB); + } + + protected void assertTargetDefinitionsEqual(ITargetDefinition targetA, ITargetDefinition targetB) throws CoreException{ + assertTrue("Target content not equal",((TargetDefinition)targetA).isContentEqual(targetB)); + } + + /** + * Reads a target definition file from the tests/targets/target-files location + * with the given name. Note that ".target" will be appended. + * + * @param name + * @return target definition + * @throws Exception + */ + protected ITargetDefinition readOldTarget(String name) throws Exception { + URL url = MacroPlugin.getBundleContext().getBundle().getEntry("/tests/targets/target-files/" + name + ".target"); + File file = new File(FileLocator.toFileURL(url).getFile()); + ITargetDefinition target = getTargetService().newTarget(); + FileInputStream stream = new FileInputStream(file); + TargetDefinitionPersistenceHelper.initFromXML(target, stream); + stream.close(); + return target; + } + + /** + * Tests that we can de-serialize an old style target definition file (version 3.2) and retrieve the correct + * contents. + * + * @throws Exception + */ + public void testReadOldBasicTargetFile() throws Exception { + ITargetDefinition target = readOldTarget("basic"); + + assertEquals("Wrong name", "Basic", target.getName()); + assertNull(target.getDescription()); + assertNull(target.getArch()); + assertNull(target.getOS()); + assertNull(target.getNL()); + assertNull(target.getWS()); + assertNull(target.getProgramArguments()); + assertNull(target.getVMArguments()); + assertNull(target.getImplicitDependencies()); + assertNull(target.getJREContainer()); + + IBundleContainer[] containers = target.getBundleContainers(); + assertEquals("Wrong number of bundles", 1, containers.length); + assertTrue("Container should be a profile container", containers[0] instanceof ProfileBundleContainer); + assertEquals("Wrong home location", new Path(TargetPlatform.getDefaultLocation()), + new Path(getResolvedLocation(containers[0]))); + } + + /** + * Tests that we can de-serialize an old style target definition file (version 3.2) and retrieve the correct + * contents. + * + * @throws Exception + */ + public void testReadOldBasicDirectoryTargetFile() throws Exception { + ITargetDefinition target = readOldTarget("directory"); + + assertEquals("Wrong name", "Directory", target.getName()); + assertNull(target.getDescription()); + assertNull(target.getArch()); + assertNull(target.getOS()); + assertNull(target.getNL()); + assertNull(target.getWS()); + assertNull(target.getProgramArguments()); + assertNull(target.getVMArguments()); + assertNull(target.getImplicitDependencies()); + assertNull(target.getJREContainer()); + + IBundleContainer[] containers = target.getBundleContainers(); + assertEquals("Wrong number of bundles", 1, containers.length); + assertTrue("Container should be a directory container", containers[0] instanceof DirectoryBundleContainer); + assertEquals("Wrong home location", new Path(TargetPlatform.getDefaultLocation()).append("plugins"), + new Path(getResolvedLocation(containers[0]))); + } + + /** + * Tests that we can de-serialize an old style target definition file (version 3.2) and retrieve the correct + * contents. + * + * @throws Exception + */ + public void testReadOldSpecificTargetFile() throws Exception { + ITargetDefinition target = readOldTarget("specific"); + + assertEquals("Wrong name", "Specific Settings", target.getName()); + assertNull(target.getDescription()); + assertEquals("x86", target.getArch()); + assertEquals("linux", target.getOS()); + assertEquals("en_US", target.getNL()); + assertEquals("gtk", target.getWS()); + assertEquals("pgm1 pgm2", target.getProgramArguments()); + assertEquals("-Dfoo=\"bar\"", target.getVMArguments()); + assertEquals(JavaRuntime.newJREContainerPath(JavaRuntime.getExecutionEnvironmentsManager().getEnvironment("J2SE-1.4")), target.getJREContainer()); + + BundleInfo[] infos = target.getImplicitDependencies(); + assertEquals("Wrong number of implicit dependencies", 2, infos.length); + Set set = new HashSet(); + for (int i = 0; i < infos.length; i++) { + set.add(infos[i].getSymbolicName()); + } + assertTrue("Missing ", set.remove("org.eclipse.jdt.debug")); + assertTrue("Missing ", set.remove("org.eclipse.debug.core")); + assertTrue(set.isEmpty()); + + IBundleContainer[] containers = target.getBundleContainers(); + assertEquals("Wrong number of bundles", 1, containers.length); + assertTrue("Container should be a directory container", containers[0] instanceof DirectoryBundleContainer); + assertEquals("Wrong home location", new Path(TargetPlatform.getDefaultLocation()).append("plugins"), + new Path(getResolvedLocation(containers[0]))); + } + + /** + * Tests that we can de-serialize an old style target definition file (version 3.2) and retrieve the correct + * contents. + * + * @throws Exception + */ + public void testReadOldAdditionLocationsTargetFile() throws Exception { + ITargetDefinition target = readOldTarget("additionalLocations"); + + assertEquals("Wrong name", "Additional Locations", target.getName()); + assertNull(target.getDescription()); + assertNull(target.getArch()); + assertNull(target.getOS()); + assertNull(target.getNL()); + assertNull(target.getWS()); + assertNull(target.getProgramArguments()); + assertNull(target.getVMArguments()); + assertNull(target.getJREContainer()); + assertNull(target.getImplicitDependencies()); + + IBundleContainer[] containers = target.getBundleContainers(); + assertEquals("Wrong number of bundles", 3, containers.length); + assertTrue(containers[0] instanceof ProfileBundleContainer); + assertTrue(containers[1] instanceof DirectoryBundleContainer); + assertTrue(containers[2] instanceof DirectoryBundleContainer); + + assertEquals("Wrong home location", new Path(TargetPlatform.getDefaultLocation()), + new Path(getResolvedLocation(containers[0]))); + + String string = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution("${workspace_loc}"); + assertEquals("Wrong 1st additional location", new Path(string).append("stuff"), + new Path(getResolvedLocation(containers[1]))); + + assertEquals("Wrong 2nd additional location", new Path(TargetPlatform.getDefaultLocation()).append("dropins"), + new Path(getResolvedLocation(containers[2]))); + } + + /** + * Tests that we can de-serialize an old style target definition file (version 3.2) and retrieve the correct + * contents. + * + * @throws Exception + */ + public void testReadOldFeaturesTargetFile() throws Exception { + ITargetDefinition target = readOldTarget("featureLocations"); + + assertEquals("Wrong name", "Features", target.getName()); + assertNull(target.getDescription()); + assertNull(target.getArch()); + assertNull(target.getOS()); + assertNull(target.getNL()); + assertNull(target.getWS()); + assertNull(target.getProgramArguments()); + assertNull(target.getVMArguments()); + assertNull(target.getJREContainer()); + assertNull(target.getImplicitDependencies()); + + IBundleContainer[] containers = target.getBundleContainers(); + assertEquals("Wrong number of bundles", 3, containers.length); + assertTrue(containers[0] instanceof ProfileBundleContainer); + assertTrue(containers[1] instanceof FeatureBundleContainer); + assertTrue(containers[2] instanceof FeatureBundleContainer); + + assertEquals("Wrong home location", new Path(TargetPlatform.getDefaultLocation()), + new Path(getResolvedLocation(containers[0]))); + + assertEquals("Wrong 1st additional location", "org.eclipse.jdt", ((FeatureBundleContainer)containers[1]).getFeatureId()); + assertEquals("Wrong 1st additional location", "org.eclipse.platform", ((FeatureBundleContainer)containers[2]).getFeatureId()); + } + + /** + * Tests that we can de-serialize an old style target definition file (version 3.2) and retrieve the correct + * contents. + * + * @throws Exception + */ + public void testReadOldRestrictionsTargetFile() throws Exception { + ITargetDefinition target = readOldTarget("restrictions"); + + assertEquals("Wrong name", "Restrictions", target.getName()); + assertNull(target.getDescription()); + assertNull(target.getArch()); + assertNull(target.getOS()); + assertNull(target.getNL()); + assertNull(target.getWS()); + assertNull(target.getProgramArguments()); + assertNull(target.getVMArguments()); + assertNull(target.getJREContainer()); + assertNull(target.getImplicitDependencies()); + + BundleInfo[] restrictions = new BundleInfo[]{ + new BundleInfo("org.eclipse.debug.core", null, null, BundleInfo.NO_LEVEL, false), + new BundleInfo("org.eclipse.debug.ui", null, null, BundleInfo.NO_LEVEL, false), + new BundleInfo("org.eclipse.jdt.debug", null, null, BundleInfo.NO_LEVEL, false), + new BundleInfo("org.eclipse.jdt.debug.ui", null, null, BundleInfo.NO_LEVEL, false), + new BundleInfo("org.eclipse.jdt.launching", null, null, BundleInfo.NO_LEVEL, false) + }; + + IBundleContainer[] containers = target.getBundleContainers(); + assertEquals("Wrong number of bundles", 3, containers.length); + assertTrue(containers[0] instanceof ProfileBundleContainer); + assertTrue(containers[1] instanceof FeatureBundleContainer); + assertTrue(containers[2] instanceof DirectoryBundleContainer); + + assertEquals("Wrong home location", new Path(TargetPlatform.getDefaultLocation()), new Path(getResolvedLocation(containers[0]))); + assertEquals("Wrong 1st additional location", "org.eclipse.jdt",((FeatureBundleContainer)containers[1]).getFeatureId()); + assertEquals("Wrong 2nd additional location", new Path(TargetPlatform.getDefaultLocation()).append("dropins"), + new Path(getResolvedLocation(containers[2]))); + + for (int i = 0; i < containers.length; i++) { + IBundleContainer container = containers[i]; + BundleInfo[] actual = container.getRestrictions(); + assertNotNull(actual); + assertEquals("Wrong number of restrictions", restrictions.length, actual.length); + for (int j = 0; j < actual.length; j++) { + assertEquals("Wrong restriction", restrictions[j], actual[j]); + } + } + } + + /** + * Tests resolution of implicit dependencies in a default target platform + * + * @throws Exception + */ + public void testImplicitDependencies() throws Exception { + ITargetDefinition definition = getTargetService().newTarget(); + IBundleContainer container = getTargetService().newProfileContainer(TargetPlatform.getDefaultLocation(), null); + definition.setBundleContainers(new IBundleContainer[]{container}); + BundleInfo[] implicit = new BundleInfo[]{ + new BundleInfo("org.eclipse.jdt.launching", null, null, BundleInfo.NO_LEVEL, false), + new BundleInfo("org.eclipse.jdt.debug", null, null, BundleInfo.NO_LEVEL, false) + }; + definition.setImplicitDependencies(implicit); + BundleInfo[] infos = definition.resolveImplicitDependencies(null); + + assertEquals("Wrong number of bundles", 2, infos.length); + Set set = new HashSet(); + for (int i = 0; i < infos.length; i++) { + set.add(infos[i].getSymbolicName()); + } + for (int i = 0; i < implicit.length; i++) { + BundleInfo info = implicit[i]; + set.remove(info.getSymbolicName()); + } + assertEquals("Wrong bundles", 0, set.size()); + + } + +}