Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 184374 Details for
Bug 331068
[target] Update the use of profiles
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Patch with API removed
clipboard.txt (text/plain), 86.68 KB, created by
Curtis Windatt
on 2010-12-02 13:23:14 EST
(
hide
)
Description:
Patch with API removed
Filename:
MIME Type:
Creator:
Curtis Windatt
Created:
2010-12-02 13:23:14 EST
Size:
86.68 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.pde.core >Index: src/org/eclipse/pde/internal/core/target/Messages.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/Messages.java,v >retrieving revision 1.10 >diff -u -r1.10 Messages.java >--- src/org/eclipse/pde/internal/core/target/Messages.java 5 Nov 2010 15:56:16 -0000 1.10 >+++ src/org/eclipse/pde/internal/core/target/Messages.java 2 Dec 2010 18:13:55 -0000 >@@ -34,6 +34,7 @@ > public static String IUBundleContainer_0; > public static String IUBundleContainer_1; > public static String IUBundleContainer_10; >+ public static String IUBundleContainer_11; > public static String IUBundleContainer_2; > public static String IUBundleContainer_3; > public static String IUBundleContainer_4; >Index: src/org/eclipse/pde/internal/core/target/Messages.properties >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/Messages.properties,v >retrieving revision 1.10 >diff -u -r1.10 Messages.properties >--- src/org/eclipse/pde/internal/core/target/Messages.properties 5 Nov 2010 15:56:16 -0000 1.10 >+++ src/org/eclipse/pde/internal/core/target/Messages.properties 2 Dec 2010 18:13:55 -0000 >@@ -25,14 +25,15 @@ > FeatureBundleContainer_5=Plug-ins directory does not exist for feature {0} > IUBundleContainer_0=Provisioning target > IUBundleContainer_1=Unable to locate installable unit {0} >-IUBundleContainer_10=Provisioning Agent service not found >+IUBundleContainer_10=Provisioning Agent Location service not found >+IUBundleContainer_11=Global Provisioning Agent service not found > IUBundleContainer_2=Metadata repository service not found > IUBundleContainer_3=Artifact respository service not found > IUBundleContainer_4=Provisioning engine not found > IUBundleContainer_5=Provisioning planner not found > IUBundleContainer_6=Target provisioning skipped install plan > IUBundleContainer_7=Provisioning agent not found >-IUBundleContainer_8=Profile registry service not found >+IUBundleContainer_8=Profile Registry service not found > IUBundleContainer_9=Garbage Collector service not found > IUBundleContainer_LoadingFromProfileJob=Loading target information from profile > IUBundleContainer_NoBundlePool=No location for downloaded bundles could be found. >Index: src/org/eclipse/pde/internal/core/target/P2TargetUtils.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/P2TargetUtils.java,v >retrieving revision 1.1 >diff -u -r1.1 P2TargetUtils.java >--- src/org/eclipse/pde/internal/core/target/P2TargetUtils.java 5 Nov 2010 15:56:16 -0000 1.1 >+++ src/org/eclipse/pde/internal/core/target/P2TargetUtils.java 2 Dec 2010 18:13:55 -0000 >@@ -12,27 +12,36 @@ > > import java.io.File; > import java.net.URI; >+import java.net.URISyntaxException; > import java.util.*; > import org.eclipse.core.runtime.*; > import org.eclipse.core.runtime.preferences.IPreferencesService; >+import org.eclipse.equinox.internal.p2.director.PermissiveSlicer; >+import org.eclipse.equinox.internal.p2.engine.*; >+import org.eclipse.equinox.internal.p2.engine.phases.*; > import org.eclipse.equinox.internal.p2.garbagecollector.GarbageCollector; > import org.eclipse.equinox.p2.core.*; > import org.eclipse.equinox.p2.engine.*; > import org.eclipse.equinox.p2.engine.query.IUProfilePropertyQuery; >-import org.eclipse.equinox.p2.metadata.IInstallableUnit; >+import org.eclipse.equinox.p2.engine.spi.ProvisioningAction; >+import org.eclipse.equinox.p2.metadata.*; >+import org.eclipse.equinox.p2.metadata.MetadataFactory.InstallableUnitDescription; > import org.eclipse.equinox.p2.metadata.Version; > import org.eclipse.equinox.p2.planner.IPlanner; >-import org.eclipse.equinox.p2.query.IQueryResult; >-import org.eclipse.equinox.p2.repository.artifact.IArtifactRepositoryManager; >-import org.eclipse.equinox.p2.repository.artifact.IFileArtifactRepository; >-import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository; >+import org.eclipse.equinox.p2.planner.IProfileChangeRequest; >+import org.eclipse.equinox.p2.query.*; >+import org.eclipse.equinox.p2.repository.*; >+import org.eclipse.equinox.p2.repository.artifact.*; > import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager; >+import org.eclipse.osgi.util.NLS; > import org.eclipse.pde.internal.core.PDECore; > import org.eclipse.pde.internal.core.target.provisional.*; > import org.osgi.framework.*; > > public class P2TargetUtils { > >+ private static final String SOURCE_IU_ID = "org.eclipse.pde.core.target.source.bundles"; //$NON-NLS-1$ >+ > /** > * URI to the local directory where the p2 agent keeps its information. > */ >@@ -81,6 +90,63 @@ > static final String PROP_ALL_ENVIRONMENTS = PDECore.PLUGIN_ID + ".all_environments"; //$NON-NLS-1$ > > /** >+ * Profile property that keeps track of the target sequence number >+ */ >+ static final String PROP_SEQUENCE_NUMBER = PDECore.PLUGIN_ID + ".sequence"; //$NON-NLS-1$ >+ >+ /** >+ * Profile property that tracks whether or not source to be auto-included >+ */ >+ static final String PROP_AUTO_INCLUDE_SOURCE = PDECore.PLUGIN_ID + ".autoIncludeSource"; //$NON-NLS-1$ >+ >+ /** >+ * The profile to be synchronized >+ */ >+ private IProfile fProfile; >+ >+ /** >+ * The target to be synchronized. >+ */ >+ private ITargetDefinition fTarget; >+ >+ /** >+ * Whether this container must have all required IUs of the selected IUs available and included >+ * in the target to resolve successfully. If this option is true, the planner will be used to resolve >+ * otherwise the slicer is used. The planner can describe any missing requirements as errors. >+ * <p> >+ * <code>true</code> by default >+ * </p> >+ */ >+ private boolean fIncludeAllRequired = true; >+ >+ /** >+ * Whether this container should download and include environment (platform) specific units for all >+ * available platforms (vs only the current target definition's environment settings). Only supported >+ * by the slicer so {@link fIncludeAllRequired} must be turned off for this setting to be used. >+ * <p> >+ * <code>false</code> by default >+ * </p> >+ */ >+ private boolean fIncludeMultipleEnvironments = false; >+ >+ /** >+ * Whether this container should download and include source bundles for the selected units if the associated >+ * source is available in the repository. >+ * <p> >+ * <code>false</code>by default >+ */ >+ private boolean fIncludeSource = false; >+ >+ /** >+ * Whether or not this synchronizer is dirty by means other than target tweaks etc. >+ */ >+ private boolean fDirty = false; >+ >+ public P2TargetUtils(ITargetDefinition target) { >+ fTarget = target; >+ } >+ >+ /** > * Deletes any profiles associated with target definitions that no longer exist > * and returns a list of profile identifiers that were deleted. > */ >@@ -93,8 +159,8 @@ > for (int i = 0; i < profiles.length; i++) { > IProfile profile = profiles[i]; > String id = profile.getProfileId(); >- if (id.startsWith(P2TargetUtils.PROFILE_ID_PREFIX)) { >- String memento = id.substring(P2TargetUtils.PROFILE_ID_PREFIX.length()); >+ if (id.startsWith(PROFILE_ID_PREFIX)) { >+ String memento = id.substring(PROFILE_ID_PREFIX.length()); > ITargetHandle handle = tps.getTarget(memento); > if (!handle.exists()) { > deleteProfile(handle); >@@ -154,7 +220,7 @@ > try { > IProfile[] profiles = getProfileRegistry().getProfiles(); > for (int i = 0; i < profiles.length; i++) { >- if (profiles[i].getProfileId().startsWith(P2TargetUtils.PROFILE_ID_PREFIX)) { >+ if (profiles[i].getProfileId().startsWith(PROFILE_ID_PREFIX)) { > getGarbageCollector().runGC(profiles[i]); > } > } >@@ -169,7 +235,7 @@ > * > * @return environment properties > */ >- private static String generateEnvironmentProperties(ITargetDefinition target) { >+ private String generateEnvironmentProperties(ITargetDefinition target) { > // TODO: are there constants for these keys? > StringBuffer env = new StringBuffer(); > String ws = target.getWS(); >@@ -200,7 +266,7 @@ > * > * @return NL profile property > */ >- private static String generateNLProperty(ITargetDefinition target) { >+ private String generateNLProperty(ITargetDefinition target) { > String nl = target.getNL(); > if (nl == null) { > nl = Platform.getNL(); >@@ -246,7 +312,7 @@ > public static IProvisioningAgent getGlobalAgent() throws CoreException { > IProvisioningAgent agent = (IProvisioningAgent) PDECore.getDefault().acquireService(IProvisioningAgent.SERVICE_NAME); > if (agent == null) >- throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, Messages.IUBundleContainer_10)); >+ throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, Messages.IUBundleContainer_11)); > return agent; > } > >@@ -278,22 +344,23 @@ > } > > /** >- * Returns the local bundle pool (repository) where bundles are stored for the >- * given profile. >+ * Returns the local bundle pool (repository) where bundles are stored > * >- * @param profile profile bundles are stored > * @return local file artifact repository > * @throws CoreException > */ >- public static IFileArtifactRepository getBundlePool(IProfile profile) throws CoreException { >- String path = profile.getProperty(IProfile.PROP_CACHE); >- if (path == null) { >- // We should always be setting the bundle pool, so if the bundle pool location is missing there isn't much we can do >- throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, Messages.IUBundleContainer_NoBundlePool)); >- } >- URI uri = new File(path).toURI(); >+ public static IFileArtifactRepository getBundlePool() throws CoreException { >+ URI uri = BUNDLE_POOL.toFile().toURI(); > IArtifactRepositoryManager manager = getArtifactRepositoryManager(); >- return (IFileArtifactRepository) manager.loadRepository(uri, null); >+ try { >+ if (manager.contains(uri)) >+ return (IFileArtifactRepository) manager.loadRepository(uri, null); >+ } catch (CoreException e) { >+ // could not load or there wasn't one, fall through to create >+ } >+ String repoName = "PDE Target Bundle Pool"; //$NON-NLS-1$ >+ IArtifactRepository result = manager.createRepository(uri, repoName, IArtifactRepositoryManager.TYPE_SIMPLE_REPOSITORY, null); >+ return (IFileArtifactRepository) result; > } > > /** >@@ -331,7 +398,7 @@ > * @throws CoreException if none > */ > public static IPlanner getPlanner() throws CoreException { >- IPlanner planner = (IPlanner) P2TargetUtils.getAgent().getService(IPlanner.class.getName()); >+ IPlanner planner = (IPlanner) getAgent().getService(IPlanner.class.getName()); > if (planner == null) { > throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, Messages.IUBundleContainer_5)); > } >@@ -348,107 +415,333 @@ > } > > /** >- * Returns the profile for the this target handle, creating one if required. >+ * Returns whether the contents of the profile matches the expected contents of the target definition > * >- * @return profile >+ * @return whether or not the profile and target definitions match > * @throws CoreException in unable to retrieve profile > */ >- public static IProfile getProfile(ITargetDefinition target) throws CoreException { >- IProfileRegistry registry = getProfileRegistry(); >- if (registry == null) { >- throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, Messages.AbstractTargetHandle_0)); >+ private boolean checkProfile() throws CoreException { >+ // make sure we have a profile to validate >+ if (fProfile == null) { >+ return false; >+ } >+ >+ if (fDirty) >+ return false; >+ // check that the target and profiles are in sync. If they are then life is good. >+ // If they are not equal, there is still a chance that everything is ok. >+ String profileNumber = fProfile.getProperty(PROP_SEQUENCE_NUMBER); >+ if (Integer.toString(((TargetDefinition) fTarget).getSequenceNumber()).equals(profileNumber)) { >+ return true; >+ } >+ >+ // check if all environments setting is the same >+ boolean all = false; >+ String value = fProfile.getProperty(PROP_ALL_ENVIRONMENTS); >+ if (value != null) { >+ all = Boolean.valueOf(value).booleanValue(); >+ if (!Boolean.toString(getIncludeAllEnvironments()).equals(value)) { >+ return false; >+ } > } >- AbstractTargetHandle handle = ((AbstractTargetHandle) target.getHandle()); >- String id = P2TargetUtils.getProfileId(handle); >- IProfile profile = registry.getProfile(id); >- if (profile != null) { >- boolean recreate = false; >- // check if all environments setting is the same >- boolean all = false; >- String value = profile.getProperty(P2TargetUtils.PROP_ALL_ENVIRONMENTS); >- if (value != null) { >- all = Boolean.valueOf(value).booleanValue(); >- if (!Boolean.toString(isAllEnvironments(target)).equals(value)) { >- recreate = true; >- } >- } >- // ensure environment & NL settings are still the same (else we need a new profile) >- String property = null; >- if (!recreate && !all) { >- property = generateEnvironmentProperties(target); >- value = profile.getProperty(IProfile.PROP_ENVIRONMENTS); >- if (!property.equals(value)) { >- recreate = true; >- } >- } >- // check provisioning mode: slice versus plan >- String mode = getProvisionMode(target); >- if (mode != null) { >- value = profile.getProperty(P2TargetUtils.PROP_PROVISION_MODE); >- if (!mode.equals(value)) { >- recreate = true; >+ >+ // ensure environment & NL settings are still the same (else we need a new profile) >+ String property = null; >+ if (!all) { >+ property = generateEnvironmentProperties(fTarget); >+ value = fProfile.getProperty(IProfile.PROP_ENVIRONMENTS); >+ if (!property.equals(value)) { >+ return false; >+ } >+ } >+ property = generateNLProperty(fTarget); >+ value = fProfile.getProperty(IProfile.PROP_NL); >+ if (!property.equals(value)) { >+ return false; >+ } >+ >+ // check provisioning mode: slice versus plan >+ if (!getProvisionMode(fTarget).equals(fProfile.getProperty(PROP_PROVISION_MODE))) { >+ return false; >+ } >+ >+ // check that the include source flag matches what the profile represents >+ if (getIncludeSource() != Boolean.valueOf(fProfile.getProperty(PROP_AUTO_INCLUDE_SOURCE)).booleanValue()) { >+ return false; >+ } >+ >+ // check top level IU's. If any have been removed from the containers that are >+ // still in the profile, we need to recreate (rather than uninstall) >+ IUProfilePropertyQuery propertyQuery = new IUProfilePropertyQuery(PROP_INSTALLED_IU, Boolean.toString(true)); >+ IQueryResult queryResult = fProfile.query(propertyQuery, null); >+ Iterator iterator = queryResult.iterator(); >+ Set installedIUs = new HashSet(); >+ while (iterator.hasNext()) { >+ IInstallableUnit unit = (IInstallableUnit) iterator.next(); >+ installedIUs.add(new NameVersionDescriptor(unit.getId(), unit.getVersion().toString())); >+ } >+ IBundleContainer[] containers = fTarget.getBundleContainers(); >+ if (containers == null) { >+ return installedIUs.isEmpty(); >+ } >+ for (int i = 0; i < containers.length; i++) { >+ if (containers[i] instanceof IUBundleContainer) { >+ IUBundleContainer bc = (IUBundleContainer) containers[i]; >+ String[] ids = bc.getIds(); >+ Version[] versions = bc.getVersions(); >+ for (int j = 0; j < versions.length; j++) { >+ // if there is something in a container but not in the profile, recreate >+ if (!installedIUs.remove(new NameVersionDescriptor(ids[j], versions[j].toString()))) { >+ return false; >+ } > } > } >+ } >+ if (!installedIUs.isEmpty()) { >+ return false; >+ } > >- if (!recreate) { >- property = generateNLProperty(target); >- value = profile.getProperty(IProfile.PROP_NL); >- if (!property.equals(value)) { >- recreate = true; >- } >- } >- if (!recreate) { >- // check top level IU's. If any have been removed from the containers that are >- // still in the profile, we need to recreate (rather than uninstall) >- IUProfilePropertyQuery propertyQuery = new IUProfilePropertyQuery(P2TargetUtils.PROP_INSTALLED_IU, Boolean.toString(true)); >- IQueryResult queryResult = profile.query(propertyQuery, null); >- Iterator iterator = queryResult.iterator(); >- if (iterator.hasNext()) { >- Set installedIUs = new HashSet(); >- while (iterator.hasNext()) { >- IInstallableUnit unit = (IInstallableUnit) iterator.next(); >- installedIUs.add(new NameVersionDescriptor(unit.getId(), unit.getVersion().toString())); >- } >- IBundleContainer[] containers = target.getBundleContainers(); >- if (containers != null) { >- for (int i = 0; i < containers.length; i++) { >- if (containers[i] instanceof IUBundleContainer) { >- IUBundleContainer bc = (IUBundleContainer) containers[i]; >- String[] ids = bc.getIds(); >- Version[] versions = bc.getVersions(); >- for (int j = 0; j < versions.length; j++) { >- installedIUs.remove(new NameVersionDescriptor(ids[j], versions[j].toString())); >- } >- } >- } >- } >- if (!installedIUs.isEmpty()) { >- recreate = true; >- } >+ // Phew! seems like the profile checks out. >+ return true; >+ } >+ >+ /** >+ * Sets whether all required units must be available to resolve this container. When <code>true</code> >+ * the resolve operation will use the planner to determine the complete set of IUs required to >+ * make the selected IUs runnable. If any dependencies are missing, the resolve operation will return an >+ * error explaining what problems exist. When <code>false</code> the resolve operation will use the slicer >+ * to determine what units to include. Any required units that are not available in the repositories will >+ * be ignored. >+ * <p> >+ * Since there is only one profile per target and the planner and slicer resolve methods are incompatible. >+ * </p> >+ * @param value whether all required units must be available to resolve this container >+ */ >+ public void setIncludeAllRequired(boolean value) { >+ fIncludeAllRequired = value; >+ } >+ >+ /** >+ * Returns whether all required units must be available to resolve this container. When <code>true</code> >+ * the resolve operation will use the planner to determine the complete set of IUs required to >+ * make the selected IUs runnable. If any dependencies are missing, the resolve operation will return an >+ * error explaining what problems exist. When <code>false</code> the resolve operation will use the slicer >+ * to determine what units to include. Any required units that are not available in the repositories will >+ * be ignored. >+ * >+ * @return whether all required units must be available to resolve this container >+ */ >+ public boolean getIncludeAllRequired() { >+ return fIncludeAllRequired; >+ } >+ >+ /** >+ * Sets whether all environment (platform) specific installable units should >+ * be included in this container when it is resolved. This feature is not supported >+ * by the planner so will only have an effect if the include all required setting >+ * is turned off ({@link #getIncludeAllRequired()}). >+ * <p> >+ * There is only one profile per target and this setting can only be set for the >+ * entire target definition. >+ * </p> >+ * @param value whether environment specific units should be included >+ */ >+ public void setIncludeAllEnvironments(boolean value) { >+ fIncludeMultipleEnvironments = value; >+ } >+ >+ /** >+ * Returns whether all environment (platform) specific installable units should >+ * be included in this container when it is resolved. This feature is not supported >+ * by the planner so will only have an effect if the include all required setting >+ * is turned off ({@link #getIncludeAllRequired()}). >+ * >+ * @return whether environment specific units should be included >+ */ >+ public boolean getIncludeAllEnvironments() { >+ return fIncludeMultipleEnvironments; >+ } >+ >+ /** >+ * Set whether or not the source bundles corresponding to any binary bundles should >+ * be automatically included in the target. >+ * >+ * @param value whether or not to include source >+ */ >+ public void setIncludeSource(boolean value) { >+ fIncludeSource = value; >+ } >+ >+ /** >+ * Returns whether or not source bundles corresponding to selected binary bundles >+ * are automatically included in the target. >+ * >+ * @return whether or not source is included automatically >+ */ >+ public boolean getIncludeSource() { >+ return fIncludeSource; >+ } >+ >+ /** >+ * Return whether or not the given target has a matching profile that is in sync >+ * @param target the target to check >+ * @return whether or not the target has been resolved at the p2 level >+ */ >+ public static boolean isResolved(ITargetDefinition target) { >+ P2TargetUtils synchronizer = getSynchronizer(target); >+ if (synchronizer == null) >+ return false; >+ try { >+ return synchronizer.checkProfile(); >+ } catch (CoreException e) { >+ return false; >+ } >+ } >+ >+ /** >+ * Get the synchronizer to use for the given target. If there is already one on a >+ * container in the target, use that one. Otherwise, create a new one. Either way, >+ * ensure that all other IU containers in the target are using the same synchronizer. >+ * <p> >+ * The synchronizer is an instance of {@link P2TargetUtils} that has access to the >+ * profile and other p2 bits for the target. >+ * </p> >+ * >+ * @param target the target for which we are getting the synchronizer >+ * @return the discovered or created synchronizer >+ */ >+ static synchronized P2TargetUtils getSynchronizer(ITargetDefinition target) { >+ IBundleContainer[] containers = target.getBundleContainers(); >+ P2TargetUtils result = null; >+ // if there are no containers then just create/return the synchronizer >+ if (containers == null) { >+ return new P2TargetUtils(target); >+ } >+ >+ // Otherwise, look for a pre-existing synchronizer >+ for (int i = 0; i < containers.length; i++) { >+ if (containers[i] instanceof IUBundleContainer) { >+ result = ((IUBundleContainer) containers[i]).getSynchronizer(null); >+ if (result != null) { >+ break; > } > } >- if (recreate) { >- P2TargetUtils.deleteProfile(handle); >- profile = null; >- } >- } >- if (profile == null) { >- // create profile >- Map properties = new HashMap(); >- properties.put(IProfile.PROP_INSTALL_FOLDER, P2TargetUtils.INSTALL_FOLDERS.append(Long.toString(LocalTargetHandle.nextTimeStamp())).toOSString()); >- properties.put(IProfile.PROP_CACHE, P2TargetUtils.BUNDLE_POOL.toOSString()); >- properties.put(IProfile.PROP_INSTALL_FEATURES, Boolean.TRUE.toString()); >- // set up environment & NL properly so OS specific fragments are down loaded/installed >- properties.put(IProfile.PROP_ENVIRONMENTS, generateEnvironmentProperties(target)); >- properties.put(IProfile.PROP_NL, generateNLProperty(target)); >- String mode = getProvisionMode(target); >- if (mode != null) { >- properties.put(P2TargetUtils.PROP_PROVISION_MODE, mode); >- properties.put(P2TargetUtils.PROP_ALL_ENVIRONMENTS, Boolean.toString(isAllEnvironments(target))); >+ } >+ >+ // still no luck? create a new one >+ if (result == null) { >+ result = new P2TargetUtils(target); >+ } >+ >+ // finally set all the other IU containers to use the same synchronizer >+ for (int i = 0; i < containers.length; i++) { >+ if (containers[i] instanceof IUBundleContainer) { >+ ((IUBundleContainer) containers[i]).setSynchronizer(result); >+ } >+ } >+ return result; >+ } >+ >+ /** >+ * Return the set of IUs in all IU containers associated with this synchronizer. >+ * This is a helper method so we don't have to expose the profile itself. >+ * >+ * @param target the target definition to query >+ * @param monitor the progress monitor to use >+ * @return the set of associated IUs >+ * @throws CoreException if there is a problem discovering the IUs >+ */ >+ public static IQueryResult getIUs(ITargetDefinition target, IProgressMonitor monitor) throws CoreException { >+ P2TargetUtils synchronizer = getSynchronizer(target); >+ if (synchronizer == null) >+ return null; >+ synchronizer.synchronize(monitor); >+ return synchronizer.getProfile().query(QueryUtil.createIUAnyQuery(), null); >+ } >+ >+ /** >+ * Synchronize the profile and the target definition managed by this synchronizer. On return the profile will >+ * be resolved and correctly match the given target. The IUBundleContainers associated with >+ * the target will be notified of any changes in the underlying p2 profile and given an >+ * opportunity to update themselves accordingly. >+ * >+ * NOTE: this is a potentially *very* heavyweight operation. >+ * >+ * NOTE: this method is synchronized as it is effectively a "test and set" caching method. Two >+ * threads getting the profile at the same time should not execute concurrently or the profiles >+ * will get out of sync. >+ * >+ * @throws CoreException if there was a problem synchronizing >+ */ >+ public synchronized void synchronize(IProgressMonitor monitor) throws CoreException { >+ SubMonitor progress = SubMonitor.convert(monitor, 100); >+ >+ // Happiness if we have a profile and it checks out or if we can load one and it checks out. >+ if (fProfile == null) { >+ fProfile = getProfileRegistry().getProfile(getProfileId(fTarget)); >+ if (fProfile != null && checkProfile()) { >+ // if we just loaded the profile for the first time, refresh the container caches >+ notify(progress.newChild(25)); >+ return; >+ } >+ } else if (checkProfile()) { >+ return; >+ } >+ >+ // Either no profile was found or it was stale. Delete the current profile and recreate. >+ // This keeps the internal agent data clean and does not cost us much. >+ deleteProfile(fTarget.getHandle()); >+ createProfile(); >+ >+ if (progress.isCanceled()) >+ return; >+ progress.setWorkRemaining(75); >+ >+ // Now resolve the profile and refresh the relate IU containers >+ if (getIncludeAllRequired()) >+ resolveWithPlanner(progress.newChild(60)); >+ else >+ resolveWithSlicer(progress.newChild(60)); >+ >+ // If we are updating a profile then delete the old snapshot on success. >+ notify(progress.newChild(15)); >+ fDirty = false; >+ } >+ >+ private void createProfile() throws CoreException, ProvisionException { >+ // create a new profile >+ IProfileRegistry registry = getProfileRegistry(); >+ if (registry == null) { >+ throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, Messages.AbstractTargetHandle_0)); >+ } >+ Map properties = new HashMap(); >+ properties.put(IProfile.PROP_INSTALL_FOLDER, INSTALL_FOLDERS.append(Long.toString(LocalTargetHandle.nextTimeStamp())).toOSString()); >+ properties.put(IProfile.PROP_CACHE, BUNDLE_POOL.toOSString()); >+ properties.put(IProfile.PROP_INSTALL_FEATURES, Boolean.TRUE.toString()); >+ properties.put(IProfile.PROP_ENVIRONMENTS, generateEnvironmentProperties(fTarget)); >+ properties.put(IProfile.PROP_NL, generateNLProperty(fTarget)); >+ properties.put(PROP_SEQUENCE_NUMBER, Integer.toString(((TargetDefinition) fTarget).getSequenceNumber())); >+ properties.put(PROP_PROVISION_MODE, getProvisionMode(fTarget)); >+ properties.put(PROP_ALL_ENVIRONMENTS, Boolean.toString(getIncludeAllEnvironments())); >+ properties.put(PROP_AUTO_INCLUDE_SOURCE, Boolean.toString(getIncludeSource())); >+ fProfile = registry.addProfile(getProfileId(fTarget), properties); >+ } >+ >+ /** >+ * Signal the relevant bundle containers that the given profile has changed. >+ */ >+ private void notify(IProgressMonitor monitor) throws CoreException { >+ // flush the target caches first since some of them are used in rebuilding >+ // the container caches (e.g., featureModels) >+ ((TargetDefinition) fTarget).flushCaches(P2TargetUtils.BUNDLE_POOL.toOSString()); >+ // Now proactively recompute all the related container caches. >+ IBundleContainer[] containers = fTarget.getBundleContainers(); >+ for (int i = 0; i < containers.length; i++) { >+ IBundleContainer container = containers[i]; >+ if (container instanceof IUBundleContainer) { >+ ((IUBundleContainer) container).synchronizerChanged(); > } >- profile = registry.addProfile(id, properties); > } >- return profile; > } > > /** >@@ -466,6 +759,22 @@ > } > > /** >+ * Returns the profile identifier for this target handle. There is one profile >+ * per target definition. >+ * >+ * @return definition the target to lookup >+ * @throws CoreException in unable to generate identifier >+ */ >+ public static String getProfileId(ITargetDefinition definition) { >+ try { >+ return getProfileId(definition.getHandle()); >+ } catch (CoreException e) { >+ // gotta make sure that this never happens. all we're doing here is computing a string. >+ return null; >+ } >+ } >+ >+ /** > * Returns the profile registry or <code>null</code> > * > * @return profile registry or <code>null</code> >@@ -485,20 +794,8 @@ > * > * @return provisioning mode or <code>null</code> > */ >- private static String getProvisionMode(ITargetDefinition target) { >- IBundleContainer[] containers = target.getBundleContainers(); >- if (containers != null) { >- for (int i = 0; i < containers.length; i++) { >- if (containers[i] instanceof IUBundleContainer) { >- IUBundleContainer iu = (IUBundleContainer) containers[i]; >- if (iu.getIncludeAllRequired()) { >- return TargetDefinitionPersistenceHelper.MODE_PLANNER; >- } >- return TargetDefinitionPersistenceHelper.MODE_SLICER; >- } >- } >- } >- return null; >+ private String getProvisionMode(ITargetDefinition target) { >+ return getIncludeAllRequired() ? TargetDefinitionPersistenceHelper.MODE_PLANNER : TargetDefinitionPersistenceHelper.MODE_SLICER; > } > > /** >@@ -516,37 +813,590 @@ > } > > /** >- * Returns the metadata repository with the given URI. >+ * Return a queryable on the metadata defined in the given repo locations > * >- * @param uri location >- * @return repository >- * @throws CoreException >+ * @param repos the repos to lookup >+ * @param monitor the progress monitor >+ * @return the set of metadata repositories found >+ * @throws CoreException if there is a problem getting the repositories > */ >- public static IMetadataRepository getRepository(URI uri) throws CoreException { >+ static IQueryable getQueryableMetadata(URI[] repos, IProgressMonitor monitor) throws CoreException { > IMetadataRepositoryManager manager = getRepoManager(); >- IMetadataRepository repo = manager.loadRepository(uri, null); >- return repo; >+ if (repos == null) { >+ repos = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL); >+ } >+ >+ IProgressMonitor loadMonitor = new SubProgressMonitor(monitor, 10); >+ int repoCount = repos.length; >+ loadMonitor.beginTask(null, repoCount * 10); >+ List result = new ArrayList(repoCount); >+ MultiStatus repoStatus = new MultiStatus(PDECore.PLUGIN_ID, 0, Messages.IUBundleContainer_ProblemsLoadingRepositories, null); >+ for (int i = 0; i < repoCount; ++i) { >+ try { >+ result.add(manager.loadRepository(repos[i], new SubProgressMonitor(loadMonitor, 10))); >+ } catch (ProvisionException e) { >+ repoStatus.add(e.getStatus()); >+ } >+ } >+ loadMonitor.done(); >+ >+ if (result.size() != repos.length) { >+ throw new CoreException(repoStatus); >+ } >+ if (result.size() == 1) { >+ return (IQueryable) result.get(0); >+ } >+ return QueryUtil.compoundQueryable(result); >+ } >+ >+ /** >+ * Used to resolve the contents of this container if the user is including all required software. The p2 planner is used >+ * to determine the complete set of IUs required to run the selected software. If all requirements are met, the bundles >+ * are downloaded from the repository into the bundle pool and added to the target definition. >+ * >+ * @param monitor for reporting progress >+ * @throws CoreException if there is a problem with the requirements or there is a problem downloading >+ */ >+ private void resolveWithPlanner(IProgressMonitor monitor) throws CoreException { >+ SubMonitor subMonitor = SubMonitor.convert(monitor, Messages.IUBundleContainer_0, 200); >+ >+ // Get the root IUs for every relevant container in the target definition >+ IInstallableUnit[] units = getRootIUs(fTarget); >+ if (subMonitor.isCanceled()) { >+ return; >+ } >+ >+ // create the provisioning plan >+ IPlanner planner = getPlanner(); >+ IProfileChangeRequest request = planner.createChangeRequest(fProfile); >+ // first remove everything that was explicitly installed. Then add it back. This has the net effect of >+ // removing everything that is no longer needed. >+ computeRemovals(fProfile, request, getIncludeSource()); >+ request.addAll(Arrays.asList(units)); >+ for (int i = 0; i < units.length; i++) { >+ IInstallableUnit unit = units[i]; >+ request.setInstallableUnitProfileProperty(unit, PROP_INSTALLED_IU, Boolean.toString(true)); >+ } >+ >+ ProvisioningContext context = new ProvisioningContext(getAgent()); >+ context.setMetadataRepositories(getMetadataRepositories(fTarget)); >+ context.setArtifactRepositories(getArtifactRepositories(fTarget)); >+ >+ if (subMonitor.isCanceled()) { >+ return; >+ } >+ >+ IProvisioningPlan plan = planner.getProvisioningPlan(request, context, subMonitor.newChild(20)); >+ IStatus status = plan.getStatus(); >+ if (!status.isOK()) { >+ throw new CoreException(status); >+ } >+ setPlanProperties(plan, fTarget, TargetDefinitionPersistenceHelper.MODE_PLANNER); >+ IProvisioningPlan installerPlan = plan.getInstallerPlan(); >+ if (installerPlan != null) { >+ // this plan requires an update to the installer first, log the fact and attempt >+ // to continue, we don't want to update the running SDK while provisioning a target >+ PDECore.log(new Status(IStatus.INFO, PDECore.PLUGIN_ID, Messages.IUBundleContainer_6)); >+ } >+ subMonitor.worked(10); >+ if (subMonitor.isCanceled()) { >+ return; >+ } >+ >+ // execute the provisioning plan >+ IPhaseSet phases = createPhaseSet(); >+ IEngine engine = getEngine(); >+ IStatus result = engine.perform(plan, phases, subMonitor.newChild(100)); >+ if (subMonitor.isCanceled()) { >+ return; >+ } >+ if (!result.isOK()) { >+ throw new CoreException(result); >+ } >+ >+ // Now that we have a plan with all the binary and explicit bundles, do a second pass and add >+ // in all the source. >+ try { >+ planInSourceBundles(fProfile, context, subMonitor.newChild(60)); >+ } catch (CoreException e) { >+ // XXX Review required: is adding in the source critical or optional? >+ // We failed adding in the source so remove the intermediate profile and rethrow >+ getProfileRegistry().removeProfile(fProfile.getProfileId(), fProfile.getTimestamp()); >+ throw e; >+ } >+ } >+ >+ private void setPlanProperties(IProvisioningPlan plan, ITargetDefinition definition, String mode) { >+ plan.setProfileProperty(PROP_PROVISION_MODE, mode); >+ plan.setProfileProperty(PROP_ALL_ENVIRONMENTS, Boolean.toString(getIncludeAllEnvironments())); >+ plan.setProfileProperty(PROP_AUTO_INCLUDE_SOURCE, Boolean.toString(getIncludeSource())); >+ plan.setProfileProperty(PROP_SEQUENCE_NUMBER, Integer.toString(((TargetDefinition) definition).getSequenceNumber())); >+ } >+ >+ private IPhaseSet createPhaseSet() { >+ ArrayList phases = new ArrayList(4); >+ phases.add(new Collect(100)); >+ phases.add(new Property(1)); >+ phases.add(new Uninstall(50, true)); >+ phases.add(new Install(50)); >+ phases.add(new CollectNativesPhase(100)); >+ return new PhaseSet((Phase[]) phases.toArray(new Phase[phases.size()])); >+ } >+ >+ /** >+ * Update the given change request to remove anything that was explicitly installed >+ * including the internal source IU. >+ */ >+ private void computeRemovals(IProfile profile, IProfileChangeRequest request, boolean includeSource) { >+ // if include source is off then ensure that the source IU is removed. >+ if (!includeSource) { >+ IInstallableUnit sourceIU = getCurrentSourceIU(profile); >+ if (sourceIU != null) >+ request.remove(sourceIU); >+ } >+ // remove everything that is marked as roots. The plan will have the new roots added in anyway. >+ IQuery query = new IUProfilePropertyQuery(PROP_INSTALLED_IU, Boolean.toString(true)); >+ IQueryResult installedIUs = profile.query(query, null); >+ request.removeAll(installedIUs.toSet()); >+ } >+ >+ // run a second pass of the planner to add in the source bundles for everything that's >+ // in the current profile. >+ private void planInSourceBundles(IProfile fProfile, ProvisioningContext context, IProgressMonitor monitor) throws CoreException { >+ SubMonitor subMonitor = SubMonitor.convert(monitor, "Provisioning source bundles", 100); >+ >+ // create an IU that optionally and greedily requires the related source bundles. >+ // Completely replace any source IU that may already be in place >+ IInstallableUnit currentSourceIU = getCurrentSourceIU(fProfile); >+ >+ // determine the new version number. start at 1 >+ Version sourceVersion = Version.createOSGi(1, 0, 0); >+ if (currentSourceIU != null) { >+ Integer major = (Integer) currentSourceIU.getVersion().getSegment(0); >+ sourceVersion = Version.createOSGi(major.intValue() + 1, 0, 0); >+ } >+ IInstallableUnit sourceIU = createSourceIU(fProfile, sourceVersion); >+ >+ // call the planner again to add in the new source IU and all available source bundles >+ IPlanner planner = getPlanner(); >+ IProfileChangeRequest request = planner.createChangeRequest(fProfile); >+ if (currentSourceIU != null) >+ request.remove(currentSourceIU); >+ request.add(sourceIU); >+ IProvisioningPlan plan = planner.getProvisioningPlan(request, context, subMonitor.newChild(25)); >+ IStatus status = plan.getStatus(); >+ if (!status.isOK()) { >+ throw new CoreException(status); >+ } >+ if (subMonitor.isCanceled()) { >+ return; >+ } >+ >+ // execute the provisioning plan >+ long oldTimestamp = fProfile.getTimestamp(); >+ IPhaseSet phases = PhaseSetFactory.createDefaultPhaseSetExcluding(new String[] {PhaseSetFactory.PHASE_CHECK_TRUST, PhaseSetFactory.PHASE_CONFIGURE, PhaseSetFactory.PHASE_UNCONFIGURE, PhaseSetFactory.PHASE_UNINSTALL}); >+ IEngine engine = getEngine(); >+ plan.setProfileProperty(PROP_PROVISION_MODE, TargetDefinitionPersistenceHelper.MODE_PLANNER); >+ plan.setProfileProperty(PROP_ALL_ENVIRONMENTS, Boolean.toString(false)); >+ IStatus result = engine.perform(plan, phases, subMonitor.newChild(75)); >+ >+ if (subMonitor.isCanceled()) { >+ return; >+ } >+ if (!result.isOK()) { >+ throw new CoreException(result); >+ } >+ >+ // remove the old (intermediate) profile version now we have a new one with source. >+ getProfileRegistry().removeProfile(fProfile.getProfileId(), oldTimestamp); >+ } >+ >+ // Create and return an IU that has optional and greedy requirements on all source bundles >+ // related to bundle IUs in the given queryable. >+ private IInstallableUnit createSourceIU(IQueryable queryable, Version iuVersion) { >+ // compute the set of source bundles we could possibly need for the bundles in the profile >+ IRequirement bundleRequirement = MetadataFactory.createRequirement("org.eclipse.equinox.p2.eclipse.type", "bundle", null, null, false, false, false); //$NON-NLS-1$ //$NON-NLS-2$ >+ IQueryResult profileIUs = queryable.query(QueryUtil.createIUAnyQuery(), null); >+ ArrayList requirements = new ArrayList(); >+ for (Iterator i = profileIUs.iterator(); i.hasNext();) { >+ IInstallableUnit profileIU = (IInstallableUnit) i.next(); >+ if (profileIU.satisfies(bundleRequirement)) { >+ String id = profileIU.getId() + ".source"; //$NON-NLS-1$ >+ Version version = profileIU.getVersion(); >+ VersionRange range = new VersionRange(version, true, version, true); >+ IRequirement sourceRequirement = MetadataFactory.createRequirement("osgi.bundle", id, range, null, true, false, true); //$NON-NLS-1$ >+ requirements.add(sourceRequirement); >+ } >+ } >+ >+ InstallableUnitDescription sourceDescription = new MetadataFactory.InstallableUnitDescription(); >+ sourceDescription.setSingleton(true); >+ sourceDescription.setId(SOURCE_IU_ID); >+ sourceDescription.setVersion(iuVersion); >+ sourceDescription.addRequirements(requirements); >+ IProvidedCapability capability = MetadataFactory.createProvidedCapability(IInstallableUnit.NAMESPACE_IU_ID, SOURCE_IU_ID, iuVersion); >+ sourceDescription.setCapabilities(new IProvidedCapability[] {capability}); >+ return MetadataFactory.createInstallableUnit(sourceDescription); >+ } >+ >+ // Lookup and return (if any) the source IU in the given queryable. >+ private IInstallableUnit getCurrentSourceIU(IQueryable queryable) { >+ IQuery query = QueryUtil.createIUQuery(SOURCE_IU_ID); >+ IQueryResult list = queryable.query(query, null); >+ IInstallableUnit currentSourceIU = null; >+ if (!list.isEmpty()) >+ currentSourceIU = (IInstallableUnit) list.iterator().next(); >+ return currentSourceIU; >+ } >+ >+ /** >+ * Used to resolve the contents of this container when the user has chosen to manage the dependencies in the target >+ * themselves. The selected IUs and any required software that can be found will be retrieved from the repositories >+ * and added to the target. Any missing required software will be ignored. >+ * >+ * @param monitor for reporting progress >+ * @throws CoreException if there is a problem interacting with the repositories >+ */ >+ private void resolveWithSlicer(IProgressMonitor monitor) throws CoreException { >+ SubMonitor subMonitor = SubMonitor.convert(monitor, Messages.IUBundleContainer_0, 100); >+ >+ // resolve IUs >+ IInstallableUnit[] units = getRootIUs(fTarget); >+ if (subMonitor.isCanceled()) { >+ return; >+ } >+ >+ URI[] repositories = getMetadataRepositories(fTarget); >+ int repoCount = repositories.length; >+ if (repoCount == 0) { >+ return; >+ } >+ IQueryable allMetadata = getQueryableMetadata(repositories, subMonitor.newChild(10)); >+ >+ // do an initial slice to add everything the user requested >+ IQueryResult queryResult = slice(units, allMetadata, fTarget, subMonitor.newChild(10)); >+ if (subMonitor.isCanceled() || queryResult == null || queryResult.isEmpty()) { >+ return; >+ } >+ >+ // If we are including source then create a source IU to bring in the relevant source >+ // bundles and run the slicer again. >+ if (getIncludeSource()) { >+ // Build an IU that represents all the source bundles and slice again to add them in if available >+ IInstallableUnit sourceIU = createSourceIU(queryResult, Version.createOSGi(1, 0, 0)); >+ IInstallableUnit[] units2 = new IInstallableUnit[units.length + 1]; >+ System.arraycopy(units, 0, units2, 0, units.length); >+ units2[units.length] = sourceIU; >+ >+ queryResult = slice(units2, allMetadata, fTarget, subMonitor.newChild(10)); >+ if (subMonitor.isCanceled() || queryResult == null || queryResult.isEmpty()) { >+ return; >+ } >+ } >+ >+ IEngine engine = getEngine(); >+ ProvisioningContext context = new ProvisioningContext(getAgent()); >+ context.setMetadataRepositories(repositories); >+ context.setArtifactRepositories(getArtifactRepositories(fTarget)); >+ IProvisioningPlan plan = engine.createPlan(fProfile, context); >+ setPlanProperties(plan, fTarget, TargetDefinitionPersistenceHelper.MODE_SLICER); >+ >+ Set newSet = queryResult.toSet(); >+ Iterator itor = newSet.iterator(); >+ while (itor.hasNext()) { >+ plan.addInstallableUnit((IInstallableUnit) itor.next()); >+ } >+ for (int i = 0; i < units.length; i++) { >+ IInstallableUnit unit = units[i]; >+ plan.setInstallableUnitProfileProperty(unit, PROP_INSTALLED_IU, Boolean.toString(true)); >+ } >+ >+ // remove all units that are in the current profile but not in the new slice >+ Set toRemove = fProfile.query(QueryUtil.ALL_UNITS, null).toSet(); >+ toRemove.removeAll(newSet); >+ for (Iterator i = toRemove.iterator(); i.hasNext();) { >+ plan.removeInstallableUnit((IInstallableUnit) i.next()); >+ } >+ >+ if (subMonitor.isCanceled()) { >+ return; >+ } >+ subMonitor.worked(10); >+ >+ // execute the provisioning plan >+ IPhaseSet phases = createPhaseSet(); >+ IStatus result = engine.perform(plan, phases, subMonitor.newChild(60)); >+ if (!result.isOK()) { >+ throw new CoreException(result); >+ } >+ } >+ >+ private IQueryResult slice(IInstallableUnit[] units, IQueryable allMetadata, ITargetDefinition definition, IProgressMonitor monitor) throws CoreException { >+ SubMonitor subMonitor = SubMonitor.convert(monitor, 100); >+ // slice IUs and all prerequisites >+ PermissiveSlicer slicer = null; >+ if (getIncludeAllEnvironments()) { >+ slicer = new PermissiveSlicer(allMetadata, new HashMap(), true, false, true, true, false); >+ } else { >+ Map props = new HashMap(); >+ props.put("osgi.os", definition.getOS() != null ? definition.getOS() : Platform.getOS()); //$NON-NLS-1$ >+ props.put("osgi.ws", definition.getWS() != null ? definition.getWS() : Platform.getWS()); //$NON-NLS-1$ >+ props.put("osgi.arch", definition.getArch() != null ? definition.getArch() : Platform.getOSArch()); //$NON-NLS-1$ >+ props.put("osgi.nl", definition.getNL() != null ? definition.getNL() : Platform.getNL()); //$NON-NLS-1$ >+ props.put(IProfile.PROP_INSTALL_FEATURES, Boolean.TRUE.toString()); >+ slicer = new PermissiveSlicer(allMetadata, props, true, false, false, true, false); >+ } >+ IQueryable slice = slicer.slice(units, subMonitor.newChild(50)); >+ if (!slicer.getStatus().isOK()) { >+ throw new CoreException(slicer.getStatus()); >+ } >+ IQueryResult queryResult = null; >+ if (slice != null) >+ queryResult = slice.query(QueryUtil.createIUAnyQuery(), subMonitor.newChild(50)); >+ return queryResult; >+ } >+ >+ /** >+ * Returns the artifact repositories to consider when getting artifacts. Returns a default set of >+ * repositories if current repository settings are <code>null</code>). >+ * >+ * @return URI's of repositories to use when getting artifacts >+ * @exception CoreException >+ */ >+ private URI[] getArtifactRepositories(ITargetDefinition target) throws CoreException { >+ Set result = new HashSet(); >+ IBundleContainer[] containers = target.getBundleContainers(); >+ IArtifactRepositoryManager manager = getArtifactRepositoryManager(); >+ for (int i = 0; i < containers.length; i++) { >+ IBundleContainer container = containers[i]; >+ if (container instanceof IUBundleContainer) { >+ URI[] repos = ((IUBundleContainer) container).getRepositories(); >+ if (repos == null) { >+ repos = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL); >+ } >+ result.addAll(Arrays.asList(repos)); >+ } >+ } >+ if (useAdditionalLocalArtifacts()) { >+ // get all the artifact repos we know in the manager currently >+ result.addAll(Arrays.asList(manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL))); >+ >+ // Add in the IDE profile bundle pool and all known workspaces >+ findProfileRepos(result); >+ findWorkspaceRepos(result); >+ } >+ return (URI[]) result.toArray(new URI[result.size()]); > } > > /** >- * Returns whether software site containers are configured to provision for all environments >- * versus a single environment. >+ * return whether or not to use local artifact repositories when provisioning the target >+ */ >+ private boolean useAdditionalLocalArtifacts() { >+ // XXX consider using a preference here or another strategy if users are able to spec >+ // what local repos are to be considered. >+ return true; >+ } >+ >+ /** >+ * Add the artifact repos from the PDE target bundle pools from all known repos. For example, the list >+ * of "recent workspaces" maintained by the IDE is a good source. > * >- * @return whether all environments will be provisioned >+ * @param additionalRepos the set to which additional repos are added. > */ >- private static boolean isAllEnvironments(ITargetDefinition target) { >+ private void findWorkspaceRepos(Set additionalRepos) { >+ IPreferencesService prefs = getPreferences(); >+ if (prefs == null) >+ return; >+ String recent = prefs.getString("org.eclipse.ui.ide", "RECENT_WORKSPACES", null, null); //$NON-NLS-1$ //$NON-NLS-2$ >+ if (recent == null) >+ return; >+ String[] recents = recent.split("\n"); //$NON-NLS-1$ >+ for (int i = 0; i < recents.length; i++) { >+ String bundlePool = recents[i] + "/.metadata/.plugins/org.eclipse.pde.core/.bundle_pool"; //$NON-NLS-1$ >+ if (new File(bundlePool).exists()) { >+ URI uri; >+ try { >+ uri = new URI("file", bundlePool, null); //$NON-NLS-1$ >+ additionalRepos.add(uri); >+ } catch (URISyntaxException e) { >+ // should never happen >+ } >+ } >+ } >+ } >+ >+ /** >+ * Look through the current p2 profile (_SELF_) and add the artifact repos that make up its >+ * bundle pool, dropins location, ... This helps in the cases that you are targeting stuff that >+ * makes up your current IDE. >+ * >+ * @param additionalRepos the set to which additional repos are added. >+ */ >+ private void findProfileRepos(Set additionalRepos) { >+ try { >+ // NOTE: be sure to use the global p2 agent here as we are looking for SELF. >+ IProfileRegistry profileRegistry = (IProfileRegistry) getGlobalAgent().getService(IProfileRegistry.SERVICE_NAME); >+ if (profileRegistry == null) >+ return; >+ IProfile self = profileRegistry.getProfile(IProfileRegistry.SELF); >+ if (self == null) >+ return; >+ >+ IAgentLocation location = (IAgentLocation) getGlobalAgent().getService(IAgentLocation.SERVICE_NAME); >+ URI dataArea = location.getDataArea("org.eclipse.equinox.p2.engine"); //$NON-NLS-1$ >+ dataArea = URIUtil.append(dataArea, "profileRegistry/" + self.getProfileId() + ".profile"); //$NON-NLS-1$//$NON-NLS-2$ >+ ProfileMetadataRepository profileRepo = new ProfileMetadataRepository(getGlobalAgent(), dataArea, null); >+ Collection repos = profileRepo.getReferences(); >+ for (Iterator i = repos.iterator(); i.hasNext();) { >+ Object element = i.next(); >+ if (element instanceof IRepositoryReference) { >+ IRepositoryReference reference = (IRepositoryReference) element; >+ if (reference.getType() == IRepository.TYPE_ARTIFACT && reference.getLocation() != null) >+ additionalRepos.add(reference.getLocation()); >+ } >+ } >+ } catch (CoreException e) { >+ // if there is a problem, move on. Could log something here >+ return; >+ } >+ } >+ >+ /** >+ * Returns the IU's for the given target related to the given containers >+ * >+ * @param containers the bundle containers to filter with >+ * @return the discovered IUs >+ * @exception CoreException if unable to retrieve IU's >+ */ >+ private IInstallableUnit[] getRootIUs(ITargetDefinition definition) throws CoreException { >+ HashSet result = new HashSet(); >+ IBundleContainer[] containers = definition.getBundleContainers(); >+ for (int i = 0; i < containers.length; i++) { >+ IBundleContainer container = containers[i]; >+ if (container instanceof IUBundleContainer) { >+ IUBundleContainer iuContainer = (IUBundleContainer) container; >+ IQueryable repos = getQueryableMetadata(iuContainer.getRepositories(), new NullProgressMonitor()); >+ String[] ids = iuContainer.getIds(); >+ Version[] versions = iuContainer.getVersions(); >+ for (int j = 0; j < ids.length; j++) { >+ IQuery query = QueryUtil.createIUQuery(ids[j], versions[j]); >+ IQueryResult queryResult = repos.query(query, null); >+ if (queryResult.isEmpty()) >+ throw new CoreException(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, NLS.bind(Messages.IUBundleContainer_1, ids[j]))); >+ result.add(queryResult.iterator().next()); >+ } >+ } >+ } >+ return (IInstallableUnit[]) result.toArray(new IInstallableUnit[result.size()]); >+ } >+ >+ /** >+ * Returns the repositories to consider when resolving IU's (will return default set of >+ * repositories if current repository settings are <code>null</code>). >+ * >+ * @return URI's of repositories to use when resolving bundles >+ * @exception CoreException >+ */ >+ private URI[] getMetadataRepositories(ITargetDefinition target) throws CoreException { >+ Set result = new HashSet(); > IBundleContainer[] containers = target.getBundleContainers(); >- if (containers != null) { >- for (int i = 0; i < containers.length; i++) { >- if (containers[i] instanceof IUBundleContainer) { >- IUBundleContainer iu = (IUBundleContainer) containers[i]; >- if (iu.getIncludeAllEnvironments()) { >- return true; >- } >+ IMetadataRepositoryManager manager = getRepoManager(); >+ for (int i = 0; i < containers.length; i++) { >+ IBundleContainer container = containers[i]; >+ if (container instanceof IUBundleContainer) { >+ URI[] repos = ((IUBundleContainer) container).getRepositories(); >+ if (repos == null) { >+ repos = manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL); > } >+ result.addAll(Arrays.asList(repos)); >+ } >+ } >+ return (URI[]) result.toArray(new URI[result.size()]); >+ } >+ >+ private static final String NATIVE_ARTIFACTS = "nativeArtifacts"; //$NON-NLS-1$ >+ private static final String NATIVE_TYPE = "org.eclipse.equinox.p2.native"; //$NON-NLS-1$ >+ private static final String PARM_OPERAND = "operand"; //$NON-NLS-1$ >+ >+ protected static class CollectNativesAction extends ProvisioningAction { >+ public IStatus execute(Map parameters) { >+ InstallableUnitOperand operand = (InstallableUnitOperand) parameters.get(PARM_OPERAND); >+ IInstallableUnit installableUnit = operand.second(); >+ if (installableUnit == null) >+ return Status.OK_STATUS; >+ >+ IArtifactRepositoryManager manager; >+ try { >+ Collection toDownload = installableUnit.getArtifacts(); >+ if (toDownload == null) >+ return Status.OK_STATUS; >+ >+ List artifactRequests = (List) parameters.get(NATIVE_ARTIFACTS); >+ IArtifactRepository destinationArtifactRepository = getBundlePool(); >+ manager = getArtifactRepositoryManager(); >+ for (Iterator i = toDownload.iterator(); i.hasNext();) { >+ IArtifactKey keyToDownload = (IArtifactKey) i.next(); >+ IArtifactRequest request = manager.createMirrorRequest(keyToDownload, destinationArtifactRepository, null, null); >+ artifactRequests.add(request); >+ } >+ } catch (CoreException e) { >+ return e.getStatus(); >+ } >+ return Status.OK_STATUS; >+ } >+ >+ public IStatus undo(Map parameters) { >+ // nothing to do for now >+ return Status.OK_STATUS; >+ } >+ } >+ >+ protected static class CollectNativesPhase extends InstallableUnitPhase { >+ public CollectNativesPhase(int weight) { >+ super(NATIVE_ARTIFACTS, weight); >+ } >+ >+ protected List getActions(InstallableUnitOperand operand) { >+ IInstallableUnit unit = operand.second(); >+ if (unit != null && unit.getTouchpointType().getId().equals(NATIVE_TYPE)) { >+ return Collections.singletonList(new CollectNativesAction()); > } >+ return null; >+ } >+ >+ protected IStatus initializePhase(IProgressMonitor monitor, IProfile profile, Map parameters) { >+ parameters.put(NATIVE_ARTIFACTS, new ArrayList()); >+ parameters.put(PARM_PROFILE, profile); >+ return null; >+ } >+ >+ protected IStatus completePhase(IProgressMonitor monitor, IProfile profile, Map parameters) { >+ List artifactRequests = (List) parameters.get(NATIVE_ARTIFACTS); >+ ProvisioningContext context = (ProvisioningContext) parameters.get(PARM_CONTEXT); >+ IProvisioningAgent agent = (IProvisioningAgent) parameters.get(PARM_AGENT); >+ DownloadManager dm = new DownloadManager(context, agent); >+ for (Iterator i = artifactRequests.iterator(); i.hasNext();) { >+ dm.add((IArtifactRequest) i.next()); >+ } >+ return dm.start(monitor); > } >- return false; > } > >+ /** >+ * @return the profile associated with this synchronizer >+ */ >+ IProfile getProfile() { >+ return fProfile; >+ } >+ >+ /** >+ * @return the target definition associated with this synchronizer >+ */ >+ ITargetDefinition getTargetDefinition() { >+ return fTarget; >+ } >+ >+ void markDirty() { >+ fDirty = true; >+ } > } >Index: src/org/eclipse/pde/internal/core/target/TargetDefinition.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/TargetDefinition.java,v >retrieving revision 1.18 >diff -u -r1.18 TargetDefinition.java >--- src/org/eclipse/pde/internal/core/target/TargetDefinition.java 5 Nov 2010 15:56:16 -0000 1.18 >+++ src/org/eclipse/pde/internal/core/target/TargetDefinition.java 2 Dec 2010 18:13:56 -0000 >@@ -75,6 +75,8 @@ > private IFeatureModel[] fFeatureModels; > private IResolvedBundle[] fOtherBundles; > >+ private int fSequenceNumber = -1; >+ > /** > * Constructs a target definition based on the given handle. > */ >@@ -142,6 +144,7 @@ > * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setArch(java.lang.String) > */ > public void setArch(String arch) { >+ incrementSequenceNumber(); > fArch = arch; > } > >@@ -149,6 +152,7 @@ > * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setNL(java.lang.String) > */ > public void setNL(String nl) { >+ incrementSequenceNumber(); > fNL = nl; > } > >@@ -163,6 +167,7 @@ > * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setOS(java.lang.String) > */ > public void setOS(String os) { >+ incrementSequenceNumber(); > fOS = os; > } > >@@ -190,6 +195,7 @@ > * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setWS(java.lang.String) > */ > public void setWS(String ws) { >+ incrementSequenceNumber(); > fWS = ws; > } > >@@ -197,6 +203,7 @@ > * @see org.eclipse.pde.internal.core.target.provisional.ITargetDefinition#setBundleContainers(org.eclipse.pde.internal.core.target.provisional.IBundleContainer[]) > */ > public void setBundleContainers(IBundleContainer[] containers) { >+ incrementSequenceNumber(); > // Clear the feature model cache as it is based on the bundle container locations > fFeatureModels = null; > fOtherBundles = null; >@@ -210,6 +217,30 @@ > if (containers == null) { > fIncluded = null; > fOptional = null; >+ } else { >+ for (int i = 0; i < containers.length; i++) { >+ ((AbstractBundleContainer) containers[i]).associateWithTarget(this); >+ } >+ } >+ } >+ >+ /** >+ * Clears the any models that are cached for the given container location. >+ * >+ * @param location location to clear cache for or <code>null</code> to clear all cached models >+ */ >+ public void flushCaches(String location) { >+ // Clear the feature model cache as it is based on the bundle container locations >+ fFeatureModels = null; >+ fOtherBundles = null; >+ if (location == null) { >+ fFeaturesInLocation.clear(); >+ } else { >+ fFeaturesInLocation.remove(location); >+ } >+ if (fContainers == null) { >+ fIncluded = null; >+ fOptional = null; > } > } > >@@ -623,6 +654,7 @@ > fProgramArgs = null; > fVMArgs = null; > fWS = null; >+ fSequenceNumber = 0; > TargetDefinitionPersistenceHelper.initFromXML(this, stream); > } catch (ParserConfigurationException e) { > abort(Messages.TargetDefinition_0, e); >@@ -994,11 +1026,46 @@ > return result; > } > >+ /** >+ * @return the current UI style one of {@link #MODE_FEATURE} or {@link #MODE_PLUGIN} >+ */ > public int getUIMode() { > return fUIMode; > } > >+ /** >+ * @param mode new UI style to use, one of {@link #MODE_FEATURE} or {@link #MODE_PLUGIN} >+ */ > public void setUIMode(int mode) { > fUIMode = mode; > } >+ >+ /** >+ * Returns the current sequence number of this target. Sequence numbers change >+ * whenever something in the target that affects the set of features and bundles that >+ * would be resolved. >+ * >+ * @return the current sequence number >+ */ >+ public int getSequenceNumber() { >+ return fSequenceNumber; >+ } >+ >+ /** >+ * Increases the current sequence number. >+ * @see TargetDefinition#getSequenceNumber() >+ * @return the current sequence number after it has been increased >+ */ >+ public int incrementSequenceNumber() { >+ return ++fSequenceNumber; >+ } >+ >+ /** >+ * Convenience method to set the sequence number to a specific >+ * value. Used when loading a target from a persisted file. >+ * @param value value to set the sequence number to >+ */ >+ void setSequenceNumber(int value) { >+ fSequenceNumber = value; >+ } > } >Index: src/org/eclipse/pde/internal/core/target/TargetDefinitionPersistenceHelper.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/TargetDefinitionPersistenceHelper.java,v >retrieving revision 1.9 >diff -u -r1.9 TargetDefinitionPersistenceHelper.java >--- src/org/eclipse/pde/internal/core/target/TargetDefinitionPersistenceHelper.java 5 Nov 2010 15:56:16 -0000 1.9 >+++ src/org/eclipse/pde/internal/core/target/TargetDefinitionPersistenceHelper.java 2 Dec 2010 18:13:56 -0000 >@@ -72,6 +72,7 @@ > static final String ATTR_OPTIONAL = "optional"; //$NON-NLS-1$ > static final String ATTR_VERSION = "version"; //$NON-NLS-1$ > static final String ATTR_CONFIGURATION = "configuration"; //$NON-NLS-1$ >+ static final String ATTR_SEQUENCE_NUMBER = "sequenceNumber"; //$NON-NLS-1$ > static final String CONTENT = "content"; //$NON-NLS-1$ > static final String ATTR_USE_ALL = "useAllPlugins"; //$NON-NLS-1$ > static final String PLUGINS = "plugins"; //$NON-NLS-1$ >@@ -107,6 +108,8 @@ > rootElement.setAttribute(ATTR_INCLUDE_MODE, FEATURE); > } > >+ rootElement.setAttribute(ATTR_SEQUENCE_NUMBER, Integer.toString(((TargetDefinition) definition).getSequenceNumber())); >+ > IBundleContainer[] containers = definition.getBundleContainers(); > if (containers != null && containers.length > 0) { > Element containersElement = doc.createElement(LOCATIONS); >Index: src/org/eclipse/pde/internal/core/target/UpdateTargetJob.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/UpdateTargetJob.java,v >retrieving revision 1.1 >diff -u -r1.1 UpdateTargetJob.java >--- src/org/eclipse/pde/internal/core/target/UpdateTargetJob.java 5 Nov 2010 15:56:16 -0000 1.1 >+++ src/org/eclipse/pde/internal/core/target/UpdateTargetJob.java 2 Dec 2010 18:13:56 -0000 >@@ -73,17 +73,16 @@ > * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) > */ > protected IStatus run(IProgressMonitor monitor) { >- int totalWork = toUpdate.size(); >+ SubMonitor progress = SubMonitor.convert(monitor, Messages.UpdateTargetJob_UpdatingTarget, toUpdate.size()); > result = 0; > try { >- monitor.beginTask(Messages.UpdateTargetJob_UpdatingTarget, totalWork); > for (Iterator i = toUpdate.entrySet().iterator(); i.hasNext();) { > try { > Map.Entry entry = (Map.Entry) i.next(); > IBundleContainer container = (IBundleContainer) entry.getKey(); > monitor.subTask(NLS.bind(Messages.UpdateTargetJob_UpdatingContainer, ((AbstractBundleContainer) container).getLocation(false))); > if (container instanceof IUBundleContainer) >- result |= ((IUBundleContainer) container).update((Set) entry.getValue()); >+ result |= ((IUBundleContainer) container).update((Set) entry.getValue(), progress.newChild(1)); > } catch (CoreException e1) { > return e1.getStatus(); > } finally { >Index: src/org/eclipse/pde/internal/core/target/provisional/ITargetPlatformService.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/provisional/ITargetPlatformService.java,v >retrieving revision 1.13 >diff -u -r1.13 ITargetPlatformService.java >--- src/org/eclipse/pde/internal/core/target/provisional/ITargetPlatformService.java 28 May 2010 19:40:04 -0000 1.13 >+++ src/org/eclipse/pde/internal/core/target/provisional/ITargetPlatformService.java 2 Dec 2010 18:13:56 -0000 >@@ -10,11 +10,11 @@ > *******************************************************************************/ > package org.eclipse.pde.internal.core.target.provisional; > >-import org.eclipse.equinox.p2.metadata.IInstallableUnit; >- > import java.net.URI; > import org.eclipse.core.resources.IFile; > import org.eclipse.core.runtime.*; >+import org.eclipse.equinox.p2.metadata.IInstallableUnit; >+import org.eclipse.pde.internal.core.target.IUBundleContainer; > > /** > * A service to manage target platform definitions available to the workspace. >@@ -139,9 +139,10 @@ > * @param units installable units > * @param repositories URI's describing repository locations or <code>null</code> to use > * default repositories >+ * @param resolutionFlags bitmask of flags to control IU resolution, possible flags are {@link IUBundleContainer#INCLUDE_ALL_ENVIRONMENTS}, {@link IUBundleContainer#INCLUDE_REQUIRED}, {@link IUBundleContainer#INCLUDE_SOURCE} > * @return bundle container > */ >- public IBundleContainer newIUContainer(IInstallableUnit[] units, URI[] repositories); >+ public IBundleContainer newIUContainer(IInstallableUnit[] units, URI[] repositories, int resolutionFlags); > > /** > * Creates and returns a bundle container that contains all bundles contained in >@@ -152,9 +153,10 @@ > * @param versions version identifiers > * @param repositories URI's describing repository locations or <code>null</code> to use > * default repositories >+ * @param resolutionFlags bitmask of flags to control IU resolution, possible flags are {@link IUBundleContainer#INCLUDE_ALL_ENVIRONMENTS}, {@link IUBundleContainer#INCLUDE_REQUIRED}, {@link IUBundleContainer#INCLUDE_SOURCE} > * @return bundle container > */ >- public IBundleContainer newIUContainer(String[] unitIds, String[] versions, URI[] repositories); >+ public IBundleContainer newIUContainer(String[] unitIds, String[] versions, URI[] repositories, int resolutionFlags); > > /** > * Creates and returns a bundle container that contains all bundles referenced by >#P org.eclipse.pde.ui >Index: META-INF/MANIFEST.MF >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.ui/META-INF/MANIFEST.MF,v >retrieving revision 1.88 >diff -u -r1.88 MANIFEST.MF >--- META-INF/MANIFEST.MF 23 Nov 2010 18:56:29 -0000 1.88 >+++ META-INF/MANIFEST.MF 2 Dec 2010 18:13:57 -0000 >@@ -108,7 +108,7 @@ > org.eclipse.pde.launching;bundle-version="[3.6.0,4.0.0)";visibility:=reexport, > org.eclipse.ui.console;bundle-version="[3.5.0,4.0.0)", > org.eclipse.equinox.simpleconfigurator;bundle-version="[1.0.200,2.0.0)", >- org.eclipse.equinox.p2.repository.tools >+ org.eclipse.equinox.p2.repository.tools;bundle-version="[2.0.100,3.0.0)" > Eclipse-LazyStart: true > Import-Package: com.ibm.icu.text, > org.eclipse.jdt.debug.core >Index: src/org/eclipse/pde/internal/ui/search/dialogs/TargetRepositorySearchHandler.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/search/dialogs/TargetRepositorySearchHandler.java,v >retrieving revision 1.7 >diff -u -r1.7 TargetRepositorySearchHandler.java >--- src/org/eclipse/pde/internal/ui/search/dialogs/TargetRepositorySearchHandler.java 9 Aug 2010 21:18:08 -0000 1.7 >+++ src/org/eclipse/pde/internal/ui/search/dialogs/TargetRepositorySearchHandler.java 2 Dec 2010 18:13:57 -0000 >@@ -78,10 +78,9 @@ > ITargetPlatformService service = (ITargetPlatformService) PDECore.getDefault().acquireService(ITargetPlatformService.class.getName()); > ITargetHandle currentTarget = service.getWorkspaceTargetHandle(); > ITargetDefinition definition = currentTarget.getTargetDefinition(); >- IUBundleContainer container = (IUBundleContainer) service.newIUContainer(units, repositories); > // Force the target into slicer mode as all requirements may not be available >- container.setIncludeAllRequired(false, definition); >- container.setIncludeAllEnvironments(true, definition); >+ int flags = IUBundleContainer.INCLUDE_ALL_ENVIRONMENTS | IUBundleContainer.INCLUDE_SOURCE; >+ IUBundleContainer container = (IUBundleContainer) service.newIUContainer(units, repositories, flags); > IBundleContainer[] oldContainers = definition.getBundleContainers(); > if (oldContainers == null) { > definition.setBundleContainers(new IBundleContainer[] {container}); >Index: src/org/eclipse/pde/internal/ui/shared/target/EditBundleContainerWizard.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/shared/target/EditBundleContainerWizard.java,v >retrieving revision 1.6 >diff -u -r1.6 EditBundleContainerWizard.java >--- src/org/eclipse/pde/internal/ui/shared/target/EditBundleContainerWizard.java 5 Nov 2010 15:56:16 -0000 1.6 >+++ src/org/eclipse/pde/internal/ui/shared/target/EditBundleContainerWizard.java 2 Dec 2010 18:13:57 -0000 >@@ -10,7 +10,6 @@ > *******************************************************************************/ > package org.eclipse.pde.internal.ui.shared.target; > >-import org.eclipse.core.runtime.CoreException; > import org.eclipse.jface.dialogs.IDialogSettings; > import org.eclipse.jface.wizard.Wizard; > import org.eclipse.pde.internal.core.target.*; >@@ -50,11 +49,7 @@ > } else if (fContainer instanceof FeatureBundleContainer) { > fPage = new EditFeatureContainerPage(fContainer); > } else if (fContainer instanceof IUBundleContainer) { >- try { >- fPage = new EditIUContainerPage((IUBundleContainer) fContainer, fTarget, P2TargetUtils.getProfile(fTarget)); >- } catch (CoreException e) { >- PDEPlugin.log(e); >- } >+ fPage = new EditIUContainerPage((IUBundleContainer) fContainer, fTarget); > } > if (fPage != null) { > addPage(fPage); >Index: src/org/eclipse/pde/internal/ui/shared/target/EditIUContainerPage.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/shared/target/EditIUContainerPage.java,v >retrieving revision 1.18 >diff -u -r1.18 EditIUContainerPage.java >--- src/org/eclipse/pde/internal/ui/shared/target/EditIUContainerPage.java 5 Nov 2010 15:56:16 -0000 1.18 >+++ src/org/eclipse/pde/internal/ui/shared/target/EditIUContainerPage.java 2 Dec 2010 18:13:57 -0000 >@@ -18,7 +18,6 @@ > import org.eclipse.equinox.internal.p2.ui.actions.PropertyDialogAction; > import org.eclipse.equinox.internal.p2.ui.dialogs.*; > import org.eclipse.equinox.internal.p2.ui.query.IUViewQueryContext; >-import org.eclipse.equinox.p2.engine.IProfile; > import org.eclipse.equinox.p2.metadata.IInstallableUnit; > import org.eclipse.equinox.p2.ui.Policy; > import org.eclipse.equinox.p2.ui.ProvisioningUI; >@@ -30,6 +29,7 @@ > import org.eclipse.osgi.util.NLS; > import org.eclipse.pde.internal.core.PDECore; > import org.eclipse.pde.internal.core.target.IUBundleContainer; >+import org.eclipse.pde.internal.core.target.P2TargetUtils; > import org.eclipse.pde.internal.core.target.provisional.*; > import org.eclipse.pde.internal.ui.*; > import org.eclipse.swt.SWT; >@@ -68,11 +68,6 @@ > private IUBundleContainer fEditContainer; > > /** >- * Profile from the target >- */ >- private IProfile fProfile; >- >- /** > * Used to provide special attributes/filtering to the available iu group > */ > private IUViewQueryContext fQueryContext; >@@ -97,19 +92,18 @@ > > /** > * Constructor for creating a new container >- * @param profile profile from the parent target, used to setup the p2 UI >+ * @param definition the target definintion we are editing > */ >- protected EditIUContainerPage(ITargetDefinition definition, IProfile profile) { >+ protected EditIUContainerPage(ITargetDefinition definition) { > super("AddP2Container"); //$NON-NLS-1$ > setTitle(Messages.EditIUContainerPage_5); > setMessage(Messages.EditIUContainerPage_6); > fTarget = definition; >- fProfile = profile; > ProvisioningUI selfProvisioningUI = ProvisioningUI.getDefaultUI(); > // TODO we use the service session from the self profile. In the future we may want > // to set up our own services for the profile (separate repo managers, etc). > // We use our own new policy so we don't bash the SDK's settings. >- profileUI = new ProvisioningUI(selfProvisioningUI.getSession(), profile.getProfileId(), new Policy()); >+ profileUI = new ProvisioningUI(selfProvisioningUI.getSession(), P2TargetUtils.getProfileId(definition), new Policy()); > } > > /** >@@ -117,8 +111,8 @@ > * @param container the container to edit > * @param profile profile from the parent target, used to setup the p2 UI > */ >- protected EditIUContainerPage(IUBundleContainer container, ITargetDefinition definition, IProfile profile) { >- this(definition, profile); >+ protected EditIUContainerPage(IUBundleContainer container, ITargetDefinition definition) { >+ this(definition); > setTitle(Messages.EditIUContainerPage_7); > setMessage(Messages.EditIUContainerPage_6); > fEditContainer = container; >@@ -132,10 +126,10 @@ > if (service == null) { > PDEPlugin.log(new Status(IStatus.ERROR, PDEPlugin.getPluginId(), Messages.EditIUContainerPage_9)); > } >- IUBundleContainer container = (IUBundleContainer) service.newIUContainer(fAvailableIUGroup.getCheckedLeafIUs(), fRepoLocation != null ? new URI[] {fRepoLocation} : null); >- container.setIncludeAllRequired(fIncludeRequiredButton.getSelection(), fTarget); >- container.setIncludeAllEnvironments(fAllPlatformsButton.getSelection(), fTarget); >- container.setIncludeSource(fIncludeSourceButton.getSelection()); >+ int flags = fIncludeRequiredButton.getSelection() ? IUBundleContainer.INCLUDE_REQUIRED : 0; >+ flags |= fAllPlatformsButton.getSelection() ? IUBundleContainer.INCLUDE_ALL_ENVIRONMENTS : 0; >+ flags |= fIncludeSourceButton.getSelection() ? IUBundleContainer.INCLUDE_SOURCE : 0; >+ IUBundleContainer container = (IUBundleContainer) service.newIUContainer(fAvailableIUGroup.getCheckedLeafIUs(), fRepoLocation != null ? new URI[] {fRepoLocation} : null, flags); > return container; > } > >@@ -299,32 +293,37 @@ > }); > ((GridData) fAllPlatformsButton.getLayoutData()).horizontalIndent = 10; > fIncludeSourceButton = SWTFactory.createCheckButton(slicerGroup, Messages.EditIUContainerPage_16, null, true, 1); >+ fIncludeSourceButton.addSelectionListener(new SelectionAdapter() { >+ public void widgetSelected(SelectionEvent e) { >+ warnIfGlobalSettingChanged(); >+ } >+ }); > } > > private void warnIfGlobalSettingChanged() { >- boolean warn = false; >- if (fTarget != null) { >- IBundleContainer[] containers = fTarget.getBundleContainers(); >- if (containers != null) { >- for (int i = 0; i < containers.length; i++) { >- if (containers[i] instanceof IUBundleContainer && containers[i] != fEditContainer) { >- IUBundleContainer container = (IUBundleContainer) containers[i]; >- if (container.getIncludeAllRequired() != fIncludeRequiredButton.getSelection()) { >- warn = true; >- break; >- } >- if (!fIncludeRequiredButton.getSelection() && container.getIncludeAllEnvironments() != fAllPlatformsButton.getSelection()) { >- warn = true; >- break; >- } >- } >+ boolean noChange = true; >+ IUBundleContainer iuContainer = null; >+ IBundleContainer[] containers = fTarget.getBundleContainers(); >+ if (containers != null) { >+ // Look for a IUBundleContainer to compare against. >+ for (int i = 0; i < containers.length; i++) { >+ if (containers[i] instanceof IUBundleContainer && containers[i] != fEditContainer) { >+ iuContainer = (IUBundleContainer) containers[i]; >+ break; > } > } >+ // If there is another IU container then compare against it. No need to check them all >+ // as they will all be set the same within one target. >+ if (iuContainer != null) { >+ noChange &= fIncludeRequiredButton.getSelection() == iuContainer.getIncludeAllRequired(); >+ noChange &= fAllPlatformsButton.getSelection() == iuContainer.getIncludeAllEnvironments(); >+ noChange &= fIncludeSourceButton.getSelection() == iuContainer.getIncludeSource(); >+ } > } >- if (warn) { >- setMessage(Messages.EditIUContainerPage_4, IStatus.WARNING); >- } else { >+ if (noChange) { > setMessage(Messages.EditIUContainerPage_6); >+ } else { >+ setMessage(Messages.EditIUContainerPage_4, IStatus.WARNING); > } > } > >@@ -333,7 +332,7 @@ > */ > private void createQueryContext() { > fQueryContext = ProvUI.getQueryContext(ProvisioningUI.getDefaultUI().getPolicy()); >- fQueryContext.setInstalledProfileId(fProfile.getProfileId()); >+ fQueryContext.setInstalledProfileId(P2TargetUtils.getProfileId(fTarget)); > fQueryContext.showAlreadyInstalled(); > } > >@@ -498,7 +497,7 @@ > // Only able to check items if we don't have categories > fQueryContext.setViewType(IUViewQueryContext.AVAILABLE_VIEW_FLAT); > fAvailableIUGroup.updateAvailableViewState(); >- fAvailableIUGroup.setChecked(fEditContainer.getInstallableUnits(fProfile)); >+ fAvailableIUGroup.setChecked(fEditContainer.getInstallableUnits()); > // Make sure view is back in proper state > updateViewContext(); > IInstallableUnit[] units = fAvailableIUGroup.getCheckedLeafIUs(); >@@ -519,5 +518,4 @@ > } > } > } >- > } >Index: src/org/eclipse/pde/internal/ui/shared/target/TargetContentsGroup.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/shared/target/TargetContentsGroup.java,v >retrieving revision 1.22 >diff -u -r1.22 TargetContentsGroup.java >--- src/org/eclipse/pde/internal/ui/shared/target/TargetContentsGroup.java 1 Oct 2010 19:23:59 -0000 1.22 >+++ src/org/eclipse/pde/internal/ui/shared/target/TargetContentsGroup.java 2 Dec 2010 18:13:58 -0000 >@@ -1028,10 +1028,10 @@ > if (parent == null) { > result = fAllBundles.toArray(); > } else if (fFeaureModeButton.getSelection() && parent == OTHER_CATEGORY) { >- return ((TargetDefinition) fTargetDefinition).getOtherBundles(); >+ result = ((TargetDefinition) fTargetDefinition).getOtherBundles(); > } else if (fGrouping == GROUP_BY_CONTAINER && parent instanceof IBundleContainer) { > IBundleContainer container = (IBundleContainer) parent; >- return container.getBundles(); >+ result = container.getBundles(); > } else if (fGrouping == GROUP_BY_FILE_LOC && parent instanceof IPath) { > List bundles = (List) getFileBundleMapping().get(parent); > if (bundles != null && bundles.size() > 0) { >Index: src/org/eclipse/pde/internal/ui/wizards/exports/ExportTargetJob.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/wizards/exports/ExportTargetJob.java,v >retrieving revision 1.1 >diff -u -r1.1 ExportTargetJob.java >--- src/org/eclipse/pde/internal/ui/wizards/exports/ExportTargetJob.java 23 Nov 2010 18:56:29 -0000 1.1 >+++ src/org/eclipse/pde/internal/ui/wizards/exports/ExportTargetJob.java 2 Dec 2010 18:13:58 -0000 >@@ -15,13 +15,11 @@ > import org.eclipse.core.filesystem.*; > import org.eclipse.core.runtime.*; > import org.eclipse.core.runtime.jobs.Job; >-import org.eclipse.equinox.p2.engine.IProfile; > import org.eclipse.equinox.p2.internal.repository.tools.Repo2Runnable; > import org.eclipse.equinox.p2.internal.repository.tools.RepositoryDescriptor; > import org.eclipse.equinox.p2.metadata.IInstallableUnit; > import org.eclipse.equinox.p2.metadata.IProvidedCapability; > import org.eclipse.equinox.p2.query.IQueryResult; >-import org.eclipse.equinox.p2.query.QueryUtil; > import org.eclipse.pde.internal.core.feature.ExternalFeatureModel; > import org.eclipse.pde.internal.core.ifeature.IFeatureModel; > import org.eclipse.pde.internal.core.target.IUBundleContainer; >@@ -219,13 +217,12 @@ > } > > private void exportProfile(ITargetDefinition target, URI destination, IProgressMonitor monitor) throws CoreException { >- IProfile profile = P2TargetUtils.getProfile(target); > Repo2Runnable exporter = new Repo2Runnable(); >- exporter.addDestination(createRepoDescriptor(destination, profile.getProfileId(), RepositoryDescriptor.KIND_METADATA)); >- exporter.addDestination(createRepoDescriptor(destination, profile.getProfileId(), RepositoryDescriptor.KIND_ARTIFACT)); >- exporter.addSource(createRepoDescriptor(P2TargetUtils.getBundlePool(profile).getLocation(), null, RepositoryDescriptor.KIND_ARTIFACT)); >+ exporter.addDestination(createRepoDescriptor(destination, P2TargetUtils.getProfileId(target), RepositoryDescriptor.KIND_METADATA)); >+ exporter.addDestination(createRepoDescriptor(destination, P2TargetUtils.getProfileId(target), RepositoryDescriptor.KIND_ARTIFACT)); >+ exporter.addSource(createRepoDescriptor(P2TargetUtils.getBundlePool().getLocation(), null, RepositoryDescriptor.KIND_ARTIFACT)); > >- IQueryResult ius = profile.query(QueryUtil.createIUAnyQuery(), null); >+ IQueryResult ius = P2TargetUtils.getIUs(target, monitor); > ArrayList toExport = new ArrayList(); > for (Iterator i = ius.iterator(); i.hasNext();) { > IInstallableUnit iu = (IInstallableUnit) i.next(); >#P org.eclipse.pde.ui.tests >Index: src/org/eclipse/pde/ui/tests/target/IUBundleContainerTests.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/target/IUBundleContainerTests.java,v >retrieving revision 1.15 >diff -u -r1.15 IUBundleContainerTests.java >--- src/org/eclipse/pde/ui/tests/target/IUBundleContainerTests.java 5 Nov 2010 19:53:46 -0000 1.15 >+++ src/org/eclipse/pde/ui/tests/target/IUBundleContainerTests.java 2 Dec 2010 18:13:59 -0000 >@@ -10,10 +10,6 @@ > *******************************************************************************/ > package org.eclipse.pde.ui.tests.target; > >-import org.eclipse.pde.internal.core.target.P2TargetUtils; >- >-import java.util.Iterator; >- > import java.io.*; > import java.net.URI; > import java.net.URL; >@@ -23,8 +19,6 @@ > import org.eclipse.core.filesystem.URIUtil; > import org.eclipse.core.runtime.*; > import org.eclipse.equinox.internal.p2.core.helpers.URLUtil; >-import org.eclipse.equinox.p2.core.IProvisioningAgent; >-import org.eclipse.equinox.p2.engine.*; > import org.eclipse.equinox.p2.metadata.IInstallableUnit; > import org.eclipse.equinox.p2.query.IQueryResult; > import org.eclipse.equinox.p2.query.QueryUtil; >@@ -89,16 +83,16 @@ > } > > public void testResolveUsingProfile() throws Exception { >- String[] bundleIDs = new String[]{"feature.b.feature.group"}; >+ String[] features1 = new String[]{"feature.b.feature.group"}; >+ String[] features2 = new String[]{"feature.a.feature.group"}; > String[] expectedBundles = new String[]{"bundle.a1", "bundle.a2", "bundle.a3", "bundle.b1", "bundle.b2", "bundle.b3"}; >- String[] expectedBundles2 = new String[]{"bundle.b1", "bundle.b2", "bundle.b3"}; >+ String[] expectedBundles2 = new String[]{"bundle.a1", "bundle.a2", "bundle.a3"}; > > try { >- >- IUBundleContainer container = createContainer(bundleIDs); >+ // create a target that references just a high level root >+ IUBundleContainer container = createContainer(features1); > ITargetDefinition target = getTargetService().newTarget(); > target.setBundleContainers(new IBundleContainer[]{container}); >- > List infos = getAllBundleInfos(target); > Set names = collectAllSymbolicNames(infos); > assertEquals(expectedBundles.length, infos.size()); >@@ -106,24 +100,9 @@ > assertTrue("Missing: " + expectedBundles[i], names.contains(expectedBundles[i])); > } > >- IProfile profile = P2TargetUtils.getProfile(target); >- >- IProvisioningAgent agent = P2TargetUtils.getAgent(); >- IEngine engine = P2TargetUtils.getEngine(); >- IProvisioningPlan plan = engine.createPlan(profile, new ProvisioningContext(agent)); >- IQueryResult units = profile.query(QueryUtil.ALL_UNITS, null); >- for (Iterator iterator = units.iterator(); iterator.hasNext();) { >- IInstallableUnit unit = (IInstallableUnit) iterator.next(); >- if (unit.getId().startsWith("bundle.a")){ >- plan.removeInstallableUnit(unit); >- } >- } >- IPhaseSet phases = PhaseSetFactory.createDefaultPhaseSetExcluding(new String[] {PhaseSetFactory.PHASE_CHECK_TRUST, PhaseSetFactory.PHASE_CONFIGURE, PhaseSetFactory.PHASE_UNCONFIGURE}); >- IStatus result = engine.perform(plan, phases, null); >- >- assertTrue("Problem while provisioning: " + result.getMessage(), result.isOK()); >- >- target.resolve(null); // Force the target to reresolve (hopefully using the modified profile) >+ // Now modify the target to have just a lower level root. The extra higher level stuff should get removed. >+ container = createContainer(features2); >+ target.setBundleContainers(new IBundleContainer[]{container}); > infos = getAllBundleInfos(target); > names = collectAllSymbolicNames(infos); > assertEquals(expectedBundles2.length, infos.size()); >@@ -211,8 +190,8 @@ > */ > public void testContentEqualNull() throws Exception { > ITargetPlatformService service = getTargetService(); >- IUBundleContainer c3 = (IUBundleContainer) service.newIUContainer(new String[]{"bundle.a1", "bundle.a2"}, new String[]{"1.0.0", "1.0.0"}, null); >- IUBundleContainer c4 = (IUBundleContainer) service.newIUContainer(new String[]{"bundle.a1", "bundle.a2"}, new String[]{"1.0.0", "1.0.0"}, null); >+ IUBundleContainer c3 = (IUBundleContainer) service.newIUContainer(new String[]{"bundle.a1", "bundle.a2"}, new String[]{"1.0.0", "1.0.0"}, null, 0); >+ IUBundleContainer c4 = (IUBundleContainer) service.newIUContainer(new String[]{"bundle.a1", "bundle.a2"}, new String[]{"1.0.0", "1.0.0"}, null, 0); > assertTrue("Contents should be equivalent", c3.isContentEqual(c4)); > } > >@@ -223,8 +202,8 @@ > */ > public void testContentNotEqualNull() throws Exception { > ITargetPlatformService service = getTargetService(); >- IUBundleContainer c3 = (IUBundleContainer) service.newIUContainer(new String[]{"bundle.a1", "bundle.a2"}, new String[]{"1.0.0", "1.0.0"}, null); >- IUBundleContainer c4 = (IUBundleContainer) service.newIUContainer(new String[]{"bundle.b1", "bundle.b2"}, new String[]{"1.0.0", "1.0.0"}, null); >+ IUBundleContainer c3 = (IUBundleContainer) service.newIUContainer(new String[]{"bundle.a1", "bundle.a2"}, new String[]{"1.0.0", "1.0.0"}, null, 1); >+ IUBundleContainer c4 = (IUBundleContainer) service.newIUContainer(new String[]{"bundle.b1", "bundle.b2"}, new String[]{"1.0.0", "1.0.0"}, null, 0); > assertFalse("Contents should not be equivalent", c3.isContentEqual(c4)); > } > >@@ -356,7 +335,7 @@ > * @throws Exception > */ > protected IUBundleContainer createContainer(IInstallableUnit[] units, URI[] repositories) throws Exception { >- return (IUBundleContainer) getTargetService().newIUContainer(units, repositories); >+ return (IUBundleContainer) getTargetService().newIUContainer(units, repositories, IUBundleContainer.INCLUDE_REQUIRED); > } > > /** >@@ -473,7 +452,7 @@ > > infos = getBundleInfos(c2); > names = collectAllSymbolicNames(infos); >- bundleIds = new String[]{"bundle.b1", "bundle.b2", "bundle.b3"}; >+ bundleIds = new String[]{"bundle.a1", "bundle.a2", "bundle.a3", "bundle.b1", "bundle.b2", "bundle.b3"}; > assertEquals(bundleIds.length, infos.size()); > > for (int i = 0; i < bundleIds.length; i++) { >Index: src/org/eclipse/pde/ui/tests/target/TargetDefinitionPersistenceTests.java >=================================================================== >RCS file: /cvsroot/eclipse/pde/ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/target/TargetDefinitionPersistenceTests.java,v >retrieving revision 1.13 >diff -u -r1.13 TargetDefinitionPersistenceTests.java >--- src/org/eclipse/pde/ui/tests/target/TargetDefinitionPersistenceTests.java 25 Feb 2010 19:44:40 -0000 1.13 >+++ src/org/eclipse/pde/ui/tests/target/TargetDefinitionPersistenceTests.java 2 Dec 2010 18:13:59 -0000 >@@ -236,12 +236,8 @@ > IBundleContainer restrictedProfileContainer = getTargetService().newProfileContainer(TargetPlatform.getDefaultLocation(), null); > > // Site bundle containers with different settings >- IUBundleContainer siteContainer = (IUBundleContainer)getTargetService().newIUContainer(new IInstallableUnit[]{}, new URI[]{new URI("TESTURI"), new URI("TESTURI2")}); >- siteContainer.setIncludeAllRequired(false, null); >- siteContainer.setIncludeAllEnvironments(true, null); >- IUBundleContainer siteContainer2 = (IUBundleContainer)getTargetService().newIUContainer(new String[]{"unit1","unit2"},new String[]{"1.0", "2.0"}, new URI[]{new URI("TESTURI"), new URI("TESTURI2")}); >- siteContainer2.setIncludeAllRequired(true, null); >- siteContainer2.setIncludeAllEnvironments(false, null); >+ IUBundleContainer siteContainer = (IUBundleContainer)getTargetService().newIUContainer(new IInstallableUnit[]{}, new URI[]{new URI("TESTURI"), new URI("TESTURI2")}, IUBundleContainer.INCLUDE_ALL_ENVIRONMENTS); >+ IUBundleContainer siteContainer2 = (IUBundleContainer)getTargetService().newIUContainer(new String[]{"unit1","unit2"},new String[]{"1.0", "2.0"}, new URI[]{new URI("TESTURI"), new URI("TESTURI2")}, IUBundleContainer.INCLUDE_REQUIRED); > > NameVersionDescriptor[] restrictions = new NameVersionDescriptor[]{ > new NameVersionDescriptor("org.eclipse.jdt.launching", null),
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 331068
:
183810
|
184066
|
184185
|
184195
|
184217
|
184319
| 184374