Skip to content

Commit 9a772d2

Browse files
committed
Refresh all repositories when performing an update of IU container
Currently the IUBundleContainer#update only queries the current P2 metadata that might be cached. This can lead to situations where when a repository has "just changed" it does not see the latest metadata. As we can assume that if the user mind to hit the update button it is meant to really get the latest, this now ask the manager to update the metadata (and possibly colocated artifacts) repository.
1 parent ba8fc7f commit 9a772d2

File tree

4 files changed

+84
-15
lines changed

4 files changed

+84
-15
lines changed

ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/IUBundleContainer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ void synchronizerChanged(ITargetDefinition target) {
423423
public synchronized IUBundleContainer update(Set<String> toUpdate, IProgressMonitor monitor) throws CoreException {
424424
SubMonitor progress = SubMonitor.convert(monitor, 100);
425425
IQueryable<IInstallableUnit> source = P2TargetUtils.getQueryableMetadata(fRepos, isFollowRepositoryReferences(),
426-
progress.split(30));
426+
true, progress.split(30));
427427
boolean updated = false;
428428
List<UnitDeclaration> updatedUnits = new ArrayList<>(fIUs);
429429
SubMonitor loopProgress = progress.split(70).setWorkRemaining(updatedUnits.size());

ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/Messages.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ public class Messages extends NLS {
4747
public static String LocalTargetHandle_3;
4848
public static String LocalTargetHandle_4;
4949
public static String LocalTargetHandle_5;
50+
public static String P2TargetUtils_cant_refresh_artifacts;
51+
public static String P2TargetUtils_cant_refresh_metadata;
5052
public static String P2TargetUtils_ProvisioningSourceTask;
5153
public static String ProfileBundleContainer_0;
5254
public static String ProfileBundleContainer_2;

ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/Messages.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ LocalTargetHandle_2=Unable to generate memento for target platform
4242
LocalTargetHandle_3=Failed to delete target definition: {0}
4343
LocalTargetHandle_4=Error saving target definition {0}
4444
LocalTargetHandle_5=Error creating target file
45+
P2TargetUtils_cant_refresh_artifacts=Can't refresh artifact repository {0}
46+
P2TargetUtils_cant_refresh_metadata=Can't refresh metadata repository {0} so the reported metadata might be outdated
4547
P2TargetUtils_ProvisioningSourceTask=Provisioning source bundles
4648
ProfileBundleContainer_0=Installation directory does not exist: {0}
4749
ProfileBundleContainer_2=Configuration directory does not exist: {0}

ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/target/P2TargetUtils.java

Lines changed: 79 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
import org.eclipse.equinox.p2.repository.artifact.IFileArtifactRepository;
9393
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
9494
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager;
95+
import org.eclipse.osgi.util.NLS;
9596
import org.eclipse.pde.core.target.ITargetDefinition;
9697
import org.eclipse.pde.core.target.ITargetHandle;
9798
import org.eclipse.pde.core.target.ITargetLocation;
@@ -984,44 +985,108 @@ private static <T> T getP2Service(Class<T> key, String absentErrorMessage) throw
984985
/**
985986
* Return a queryable on the metadata defined in the given repo locations
986987
*
987-
* @param repos the repos to lookup
988-
* @param followRepositoryReferences whether to follow repository references
989-
* @param monitor the progress monitor
988+
* @param repos
989+
* the repos to lookup
990+
* @param followRepositoryReferences
991+
* whether to follow repository references
992+
* @param monitor
993+
* the progress monitor
990994
* @return the set of metadata repositories found
991-
* @throws CoreException if there is a problem getting the repositories
995+
* @throws CoreException
996+
* if there is a problem getting the repositories
992997
*/
993998
static IQueryable<IInstallableUnit> getQueryableMetadata(Collection<URI> repos, boolean followRepositoryReferences,
994999
IProgressMonitor monitor) throws CoreException {
995-
IMetadataRepositoryManager manager = getRepoManager();
1000+
return getQueryableMetadata(repos, followRepositoryReferences, false, monitor);
1001+
}
1002+
1003+
/**
1004+
* Return a queryable on the metadata defined in the given repo locations
1005+
*
1006+
* @param repos
1007+
* the repos to lookup
1008+
* @param followRepositoryReferences
1009+
* whether to follow repository references
1010+
* @param forceReload
1011+
* forces reloading of repositories
1012+
* @param monitor
1013+
* the progress monitor
1014+
* @return the set of metadata repositories found
1015+
* @throws CoreException
1016+
* if there is a problem getting the repositories
1017+
*/
1018+
static IQueryable<IInstallableUnit> getQueryableMetadata(Collection<URI> repos, boolean followRepositoryReferences,
1019+
boolean forceReload,
1020+
IProgressMonitor monitor) throws CoreException {
1021+
IMetadataRepositoryManager metadataRepositoryManager = getRepoManager();
1022+
Collection<URI> existing = new LinkedHashSet<>(
1023+
Arrays.asList(metadataRepositoryManager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL)));
9961024
if (repos.isEmpty()) {
997-
repos = Arrays.asList(manager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL));
1025+
repos = existing;
9981026
}
999-
SubMonitor subMonitor = SubMonitor.convert(monitor, repos.size() * 2);
1000-
1027+
int work = repos.size() * (forceReload ? 4 : 2);
1028+
SubMonitor subMonitor = SubMonitor.convert(monitor, work);
10011029
Set<IRepositoryReference> seen = new HashSet<>();
10021030
List<IMetadataRepository> result = new ArrayList<>(repos.size());
10031031
List<IMetadataRepository> additional = new ArrayList<>();
10041032
MultiStatus repoStatus = new MultiStatus(PDECore.PLUGIN_ID, 0, Messages.IUBundleContainer_ProblemsLoadingRepositories);
10051033
for (URI location : repos) {
10061034
try {
1007-
IMetadataRepository repository = manager.loadRepository(location, subMonitor.split(1));
1035+
IMetadataRepository repository = metadataRepositoryManager.loadRepository(location, subMonitor.split(1));
10081036
result.add(repository);
10091037
if (followRepositoryReferences) {
1010-
addReferences(repository, additional, seen, manager, subMonitor.split(1));
1038+
addReferences(repository, additional, seen, metadataRepositoryManager, subMonitor.split(1));
10111039
}
10121040
} catch (ProvisionException e) {
10131041
repoStatus.add(e.getStatus());
10141042
}
10151043
}
1016-
10171044
if (result.size() != repos.size()) {
10181045
throw new CoreException(repoStatus);
10191046
}
10201047
result.addAll(additional);
1021-
if (result.size() == 1) {
1022-
return result.get(0);
1048+
if (result.isEmpty()) {
1049+
return QueryUtil.compoundQueryable(List.of());
1050+
}
1051+
Collection<IMetadataRepository> unique = new LinkedHashSet<>(result);
1052+
if (forceReload) {
1053+
List<IMetadataRepository> refreshed = new ArrayList<>();
1054+
subMonitor.setWorkRemaining(2 * unique.size());
1055+
IArtifactRepositoryManager artifactRepositoryManager = getArtifactRepositoryManager();
1056+
metadataRepositoryManager = getRepoManager();
1057+
Collection<URI> existingArtifactRepositories = new LinkedHashSet<>(
1058+
Arrays.asList(artifactRepositoryManager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL)));
1059+
for (IMetadataRepository metadataRepository : unique) {
1060+
URI location = metadataRepository.getLocation();
1061+
if (existing.contains(location)) {
1062+
try {
1063+
refreshed.add(metadataRepositoryManager.refreshRepository(location, subMonitor.split(1)));
1064+
} catch (ProvisionException e) {
1065+
ILog.get().warn(NLS.bind(Messages.P2TargetUtils_cant_refresh_metadata, location), e);
1066+
// if refresh do not work, use the previously loaded
1067+
// repository
1068+
refreshed.add(metadataRepository);
1069+
}
1070+
if (existingArtifactRepositories.contains(location)) {
1071+
try {
1072+
artifactRepositoryManager.refreshRepository(location, subMonitor.split(1));
1073+
} catch (ProvisionException e) {
1074+
// we tried our best...
1075+
ILog.get().warn(NLS.bind(Messages.P2TargetUtils_cant_refresh_artifacts, location), e);
1076+
}
1077+
}
1078+
} else {
1079+
// the repo was just loaded as part of this call so it has
1080+
// to be (almost) fresh
1081+
refreshed.add(metadataRepository);
1082+
}
1083+
}
1084+
unique = refreshed;
1085+
}
1086+
if (unique.size() == 1) {
1087+
return unique.iterator().next();
10231088
}
1024-
return QueryUtil.compoundQueryable(new LinkedHashSet<>(result));
1089+
return QueryUtil.compoundQueryable(unique);
10251090
}
10261091

10271092
private static void addReferences(IMetadataRepository repository, List<IMetadataRepository> result,

0 commit comments

Comments
 (0)