Skip to content

Commit

Permalink
back-port: Remember referenced repositories as system repositories in…
Browse files Browse the repository at this point in the history
…stead of user

Currently there is a quite surprising behavior, that if a user adds an
updatesite that contains a referenced repository, that after an
update-check additional repositories are visible. Even worse these are
now used additionally to check for updates and if they contain other
references these are also added and so on. This can result not only in a
long list of sites the user never has added and has no clue where they
are coming from but even pulling in unwanted or conflicting updates.

This now distinguishes two cases:

1) A repository is discovered by the RepositoryAction it is handled as a
user added repository and becomes visible
2) A repository is discovered by a reference in that case it is handled
as a system repository and not becomes visible

that way the list of user visible repositories stay clean from
referenced repositories and unexpected side effects on update checks.
  • Loading branch information
laeubi authored and gireeshpunathil committed Sep 18, 2024
1 parent 89f12f7 commit b6e888e
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -185,14 +185,18 @@ public void initialize(RepositoryState state) {
* Broadcast discovery events for all repositories referenced by this repository.
*/
public void publishRepositoryReferences() {
IProvisioningEventBus bus = getProvisioningAgent().getService(IProvisioningEventBus.class);
if (bus == null)
IProvisioningAgent agent = getProvisioningAgent();
IProvisioningEventBus bus = agent.getService(IProvisioningEventBus.class);
if (bus == null) {
return;

List<IRepositoryReference> repositoriesSnapshot = createRepositoriesSnapshot();
boolean referenceAsSystem = Boolean
.parseBoolean(agent.getProperty("p2.metadata.repository.reference.system", "true")); //$NON-NLS-1$ //$NON-NLS-2$
for (IRepositoryReference reference : repositoriesSnapshot) {
boolean isEnabled = (reference.getOptions() & IRepository.ENABLED) != 0;
bus.publishEvent(new RepositoryEvent(reference.getLocation(), reference.getType(), RepositoryEvent.DISCOVERED, isEnabled));
RepositoryEvent event = RepositoryEvent.newDiscoveryEvent(reference.getLocation(), reference.getNickname(),
reference.getType(), reference.isEnabled(), referenceAsSystem);
bus.publishEvent(event);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,16 +162,19 @@ private boolean addRepository(URI location, boolean isEnabled, boolean signalAdd
info.isEnabled = isEnabled;
boolean added = true;
synchronized (repositoryLock) {
if (repositories == null)
if (repositories == null) {
restoreRepositories();
if (contains(location))
}
if (contains(info.location)) {
return false;
added = repositories.put(getKey(location), info) == null;
}
added = repositories.put(getKey(info.location), info) == null;
// save the given repository in the preferences.
remember(info, true);
}
if (added && signalAdd)
broadcastChangeEvent(location, getRepositoryType(), RepositoryEvent.ADDED, isEnabled);
if (added && signalAdd) {
broadcastChangeEvent(info.location, getRepositoryType(), RepositoryEvent.ADDED, info.isEnabled);
}
return added;
}

Expand Down Expand Up @@ -837,8 +840,14 @@ private boolean matchesFlags(RepositoryInfo<T> info, int flags) {
public void notify(EventObject o) {
if (o instanceof RepositoryEvent) {
RepositoryEvent event = (RepositoryEvent) o;
if (event.getKind() == RepositoryEvent.DISCOVERED && event.getRepositoryType() == getRepositoryType())
addRepository(event.getRepositoryLocation(), event.isRepositoryEnabled(), true);
if (event.getKind() == RepositoryEvent.DISCOVERED && event.getRepositoryType() == getRepositoryType()) {
RepositoryInfo<T> info = new RepositoryInfo<>();
info.location = event.getRepositoryLocation();
info.isEnabled = event.isRepositoryEnabled();
info.nickname = event.getRepositoryNickname();
info.isSystem = event.isSystem();
addRepository(info, true);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
Expand All @@ -21,27 +21,27 @@
/**
* An event indicating a repository was added, removed, changed,
* or discovered.
*
*
* @see IProvisioningEventBus
* @noextend This class is not intended to be subclassed by clients.
*/
public class RepositoryEvent extends EventObject {
private static final long serialVersionUID = 3082402920617281765L;

/**
* A change kind constant (value 0), indicating a repository was added to the
* A change kind constant (value 0), indicating a repository was added to the
* list of repositories known to a repository manager.
*/
public static final int ADDED = 0;

/**
* A change kind constant (value 1), indicating a repository was removed from
* A change kind constant (value 1), indicating a repository was removed from
* the list of repositories known to a repository manager.
*/
public static final int REMOVED = 1;

/**
* A change kind constant (value 2), indicating a repository known to a
* A change kind constant (value 2), indicating a repository known to a
* repository manager was modified.
*/
public static final int CHANGED = 2;
Expand All @@ -67,25 +67,48 @@ public class RepositoryEvent extends EventObject {
private final int kind, type;
private boolean isEnabled;
private String nickname;
private boolean system;

/**
* Creates and returns a new repository discovery event.
* @param location the location of the repository that changed.
* @param nickname the repository nickname
*
* @param location the location of the repository that changed.
* @param nickname the repository nickname
* @param repositoryType the type of repository that was changed
* @param enabled whether the repository is enabled
* @param enabled whether the repository is enabled
* @return A new repository discovery event
* @see IRepository#PROP_NICKNAME
*/
public static RepositoryEvent newDiscoveryEvent(URI location, String nickname, int repositoryType,
boolean enabled) {
RepositoryEvent event = new RepositoryEvent(location, repositoryType, DISCOVERED, enabled);
event.nickname = nickname;
return event;
}

/**
* Creates and returns a new repository discovery event.
*
* @param location the location of the repository that changed.
* @param nickname the repository nickname
* @param repositoryType the type of repository that was changed
* @param enabled whether the repository is enabled
* @param system whether the repository is a system repository
* @return A new repository discovery event
* @see IRepository#PROP_NICKNAME
* @since 2.9
*/
public static RepositoryEvent newDiscoveryEvent(URI location, String nickname, int repositoryType, boolean enabled) {
public static RepositoryEvent newDiscoveryEvent(URI location, String nickname, int repositoryType, boolean enabled,
boolean system) {
RepositoryEvent event = new RepositoryEvent(location, repositoryType, DISCOVERED, enabled);
event.nickname = nickname;
event.system = system;
return event;
}

/**
* Creates a new repository event.
*
*
* @param location the location of the repository that changed.
* @param repositoryType the type of repository that was changed
* @param kind the kind of change that occurred.
Expand Down Expand Up @@ -121,9 +144,21 @@ public String getRepositoryNickname() {
return nickname;
}

/**
* Returns if the repository is a system type see
* {@link IRepository#PROP_SYSTEM}. This method is only applicable for the
* {@link #DISCOVERED} event type. For other event types this method returns
* <code>false</code>.
*
* @since 2.9
*/
public boolean isSystem() {
return system;
}

/**
* Returns the location of the repository associated with this event.
*
*
* @return the location of the repository associated with this event.
*/
public URI getRepositoryLocation() {
Expand All @@ -134,7 +169,7 @@ public URI getRepositoryLocation() {
* Returns the type of repository associated with this event. Clients
* should not assume that the set of possible repository types is closed;
* clients should ignore events from repository types they don't know about.
*
*
* @return the type of repository associated with this event.
* ({@link IRepository#TYPE_METADATA} or {@link IRepository#TYPE_ARTIFACT}).
*/
Expand All @@ -144,7 +179,7 @@ public int getRepositoryType() {

/**
* Returns whether the affected repository is enabled.
*
*
* @return <code>true</code> if the repository is enabled,
* and <code>false</code> otherwise.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ protected RepositoryEvent createEvent(Map<String, Object> parameters) throws Cor
// default is to be enabled
String enablement = (String) parameters.get(ActionConstants.PARM_REPOSITORY_ENABLEMENT);
boolean enabled = enablement == null ? true : Boolean.parseBoolean(enablement);
return RepositoryEvent.newDiscoveryEvent(location, name, type, enabled);
return RepositoryEvent.newDiscoveryEvent(location, name, type, enabled, false);
}

/**
Expand Down
40 changes: 40 additions & 0 deletions bundles/org.eclipse.equinox.p2.ui/.settings/.api_filters
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<component id="org.eclipse.equinox.p2.ui" version="2">
<resource path="src/org/eclipse/equinox/internal/p2/ui/model/ElementUtils.java" type="org.eclipse.equinox.internal.p2.ui.model.ElementUtils">
<filter id="640712815">
<message_arguments>
<message_argument value="Remedy"/>
<message_argument value="ElementUtils"/>
<message_argument value="getIusDetails()"/>
</message_arguments>
</filter>
<filter id="640712815">
<message_arguments>
<message_argument value="RemedyIUDetail"/>
<message_argument value="ElementUtils"/>
<message_argument value="getBeingInstalledVersion()"/>
</message_arguments>
</filter>
<filter id="640712815">
<message_arguments>
<message_argument value="RemedyIUDetail"/>
<message_argument value="ElementUtils"/>
<message_argument value="getIu()"/>
</message_arguments>
</filter>
<filter id="640712815">
<message_arguments>
<message_argument value="RemedyIUDetail"/>
<message_argument value="ElementUtils"/>
<message_argument value="getRequestedVersion()"/>
</message_arguments>
</filter>
<filter id="640712815">
<message_arguments>
<message_argument value="RemedyIUDetail"/>
<message_argument value="ElementUtils"/>
<message_argument value="getStatus()"/>
</message_arguments>
</filter>
</resource>
</component>
Original file line number Diff line number Diff line change
Expand Up @@ -35,31 +35,38 @@
*/
public class ElementUtils {

public static void updateRepositoryUsingElements(final ProvisioningUI ui, final MetadataRepositoryElement[] elements) {
public static void updateRepositoryUsingElements(final ProvisioningUI ui,
final MetadataRepositoryElement[] elements) {
ui.signalRepositoryOperationStart();
IMetadataRepositoryManager metaManager = ProvUI.getMetadataRepositoryManager(ui.getSession());
IArtifactRepositoryManager artManager = ProvUI.getArtifactRepositoryManager(ui.getSession());
try {
int visibilityFlags = ui.getRepositoryTracker().getMetadataRepositoryFlags();
URI[] currentlyEnabled = metaManager.getKnownRepositories(visibilityFlags);
URI[] currentlyDisabled = metaManager.getKnownRepositories(IRepositoryManager.REPOSITORIES_DISABLED | visibilityFlags);
URI[] currentlyDisabled = metaManager
.getKnownRepositories(IRepositoryManager.REPOSITORIES_DISABLED | visibilityFlags);
for (MetadataRepositoryElement element : elements) {
URI location = element.getLocation();
if (element.isEnabled()) {
if (containsURI(currentlyDisabled, location))
// It should be enabled and is not currently
setColocatedRepositoryEnablement(ui, location, true);
else if (!containsURI(currentlyEnabled, location)) {
// It is not known as enabled or disabled. Add it.
// It is not known as enabled or disabled. Add it.
metaManager.addRepository(location);
artManager.addRepository(location);
// even though it is not contained in the visible repositories, it could have
// been a system repository we mark it here explicitly as no longer being a
// system one
metaManager.setRepositoryProperty(location, IRepository.PROP_SYSTEM, "false"); //$NON-NLS-1$
artManager.setRepositoryProperty(location, IRepository.PROP_SYSTEM, "false"); //$NON-NLS-1$
}
} else {
if (containsURI(currentlyEnabled, location))
// It should be disabled, and is currently enabled
setColocatedRepositoryEnablement(ui, location, false);
else if (!containsURI(currentlyDisabled, location)) {
// It is not known as enabled or disabled. Add it and then disable it.
// It is not known as enabled or disabled. Add it and then disable it.
metaManager.addRepository(location);
artManager.addRepository(location);
setColocatedRepositoryEnablement(ui, location, false);
Expand All @@ -71,7 +78,7 @@ else if (!containsURI(currentlyDisabled, location)) {
artManager.setRepositoryProperty(location, IRepository.PROP_NICKNAME, name);
}
}
// Are there any elements that need to be deleted? Go over the original state
// Are there any elements that need to be deleted? Go over the original state
// and remove any elements that weren't in the elements we were given
Set<String> nowKnown = new HashSet<>();
for (MetadataRepositoryElement element : elements)
Expand Down Expand Up @@ -137,7 +144,9 @@ public static AvailableIUElement[] requestToElement(Remedy remedy, boolean insta
if (iuDetail.getStatus() == RemedyIUDetail.STATUS_NOT_ADDED)
continue;
AvailableIUElement element = new AvailableIUElement(root, iuDetail.getIu(), ui.getProfileId(), true);
if (iuDetail.getBeingInstalledVersion() != null && iuDetail.getRequestedVersion() != null && iuDetail.getBeingInstalledVersion().compareTo(iuDetail.getRequestedVersion()) < 0 && !installMode)
if (iuDetail.getBeingInstalledVersion() != null && iuDetail.getRequestedVersion() != null
&& iuDetail.getBeingInstalledVersion().compareTo(iuDetail.getRequestedVersion()) < 0
&& !installMode)
element.setImageOverlayId(ProvUIImages.IMG_INFO);
else if (iuDetail.getStatus() == RemedyIUDetail.STATUS_REMOVED)
element.setImageId(ProvUIImages.IMG_REMOVED);
Expand Down

0 comments on commit b6e888e

Please sign in to comment.