diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/IUBundleContainer.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/IUBundleContainer.java index 9c61ab98bf..af435e7ecb 100644 --- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/IUBundleContainer.java +++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/IUBundleContainer.java @@ -423,7 +423,7 @@ void synchronizerChanged(ITargetDefinition target) { public synchronized IUBundleContainer update(Set toUpdate, IProgressMonitor monitor) throws CoreException { SubMonitor progress = SubMonitor.convert(monitor, 100); IQueryable source = P2TargetUtils.getQueryableMetadata(fRepos, isFollowRepositoryReferences(), - progress.split(30)); + true, progress.split(30)); boolean updated = false; List updatedUnits = new ArrayList<>(fIUs); SubMonitor loopProgress = progress.split(70).setWorkRemaining(updatedUnits.size()); diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/Messages.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/Messages.java index 7fc442c5d4..e83df30912 100755 --- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/Messages.java +++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/Messages.java @@ -47,6 +47,8 @@ public class Messages extends NLS { public static String LocalTargetHandle_3; public static String LocalTargetHandle_4; public static String LocalTargetHandle_5; + public static String P2TargetUtils_cant_refresh_artifacts; + public static String P2TargetUtils_cant_refresh_metadata; public static String P2TargetUtils_ProvisioningSourceTask; public static String ProfileBundleContainer_0; public static String ProfileBundleContainer_2; diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/Messages.properties b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/Messages.properties index 0f6b21b9e3..6beddd27cb 100755 --- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/Messages.properties +++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/Messages.properties @@ -42,6 +42,8 @@ LocalTargetHandle_2=Unable to generate memento for target platform LocalTargetHandle_3=Failed to delete target definition: {0} LocalTargetHandle_4=Error saving target definition {0} LocalTargetHandle_5=Error creating target file +P2TargetUtils_cant_refresh_artifacts=Can't refresh artifact repository {0} +P2TargetUtils_cant_refresh_metadata=Can't refresh metadata repository {0} reported metadata might be outdated P2TargetUtils_ProvisioningSourceTask=Provisioning source bundles ProfileBundleContainer_0=Installation directory does not exist: {0} ProfileBundleContainer_2=Configuration directory does not exist: {0} diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/P2TargetUtils.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/P2TargetUtils.java index e288dbee9a..8f6abc4d09 100644 --- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/P2TargetUtils.java +++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/P2TargetUtils.java @@ -92,6 +92,7 @@ import org.eclipse.equinox.p2.repository.artifact.IFileArtifactRepository; import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository; import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager; +import org.eclipse.osgi.util.NLS; import org.eclipse.pde.core.target.ITargetDefinition; import org.eclipse.pde.core.target.ITargetHandle; import org.eclipse.pde.core.target.ITargetLocation; @@ -984,44 +985,108 @@ private static T getP2Service(Class key, String absentErrorMessage) throw /** * Return a queryable on the metadata defined in the given repo locations * - * @param repos the repos to lookup - * @param followRepositoryReferences whether to follow repository references - * @param monitor the progress monitor + * @param repos + * the repos to lookup + * @param followRepositoryReferences + * whether to follow repository references + * @param monitor + * the progress monitor * @return the set of metadata repositories found - * @throws CoreException if there is a problem getting the repositories + * @throws CoreException + * if there is a problem getting the repositories */ static IQueryable getQueryableMetadata(Collection repos, boolean followRepositoryReferences, IProgressMonitor monitor) throws CoreException { - IMetadataRepositoryManager manager = getRepoManager(); + return getQueryableMetadata(repos, followRepositoryReferences, false, monitor); + } + + /** + * Return a queryable on the metadata defined in the given repo locations + * + * @param repos + * the repos to lookup + * @param followRepositoryReferences + * whether to follow repository references + * @param forceReload + * forces reloading of repositories + * @param monitor + * the progress monitor + * @return the set of metadata repositories found + * @throws CoreException + * if there is a problem getting the repositories + */ + static IQueryable getQueryableMetadata(Collection repos, boolean followRepositoryReferences, + boolean forceReload, + IProgressMonitor monitor) throws CoreException { + IMetadataRepositoryManager metadataRepositoryManager = getRepoManager(); + Collection existing = new LinkedHashSet<>( + Arrays.asList(metadataRepositoryManager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL))); if (repos.isEmpty()) { - repos = Arrays.asList(manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL)); + repos = existing; } - SubMonitor subMonitor = SubMonitor.convert(monitor, repos.size() * 2); - + int work = repos.size() * (forceReload?4: 2); + SubMonitor subMonitor = SubMonitor.convert(monitor, work); Set seen = new HashSet<>(); List result = new ArrayList<>(repos.size()); List additional = new ArrayList<>(); MultiStatus repoStatus = new MultiStatus(PDECore.PLUGIN_ID, 0, Messages.IUBundleContainer_ProblemsLoadingRepositories); for (URI location : repos) { try { - IMetadataRepository repository = manager.loadRepository(location, subMonitor.split(1)); + IMetadataRepository repository = metadataRepositoryManager.loadRepository(location, subMonitor.split(1)); result.add(repository); if (followRepositoryReferences) { - addReferences(repository, additional, seen, manager, subMonitor.split(1)); + addReferences(repository, additional, seen, metadataRepositoryManager, subMonitor.split(1)); } } catch (ProvisionException e) { repoStatus.add(e.getStatus()); } } - if (result.size() != repos.size()) { throw new CoreException(repoStatus); } result.addAll(additional); - if (result.size() == 1) { - return result.get(0); + if (result.isEmpty()) { + return QueryUtil.compoundQueryable(List.of()); + } + Collection unique = new LinkedHashSet<>(result); + if (forceReload) { + List refreshed = new ArrayList<>(); + subMonitor.setWorkRemaining(2 * unique.size()); + IArtifactRepositoryManager artifactRepositoryManager = getArtifactRepositoryManager(); + metadataRepositoryManager = getRepoManager(); + Collection existingArtifactRepositories = new LinkedHashSet<>( + Arrays.asList(artifactRepositoryManager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL))); + for (IMetadataRepository metadataRepository : unique) { + URI location = metadataRepository.getLocation(); + if (existing.contains(location)) { + try { + refreshed.add(metadataRepositoryManager.refreshRepository(location, subMonitor.split(1))); + } catch (ProvisionException e) { + ILog.get().warn(NLS.bind(Messages.P2TargetUtils_cant_refresh_metadata, location), e); + // if refresh do not work, use the previously loaded + // repository + refreshed.add(metadataRepository); + } + if (existingArtifactRepositories.contains(location)) { + try { + artifactRepositoryManager.refreshRepository(location, subMonitor.split(1)); + } catch (ProvisionException e) { + // we tried our best... + ILog.get().warn(NLS.bind(Messages.P2TargetUtils_cant_refresh_artifacts, location), e); + } + } + } else { + // the repo was just loaded as part of this called so it has + // to be (almost) fresh + refreshed.add(metadataRepository); + } + } + unique = refreshed; + } + if (unique.size() == 1) { + return unique.iterator().next(); } - return QueryUtil.compoundQueryable(new LinkedHashSet<>(result)); + return QueryUtil.compoundQueryable(unique); } private static void addReferences(IMetadataRepository repository, List result,