Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various improvements of the TP-Editor's content-assist #1449

Merged
merged 3 commits into from
Oct 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2018, 2020 Red Hat Inc. and others
* Copyright (c) 2018, 2024 Red Hat Inc. and others
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
Expand All @@ -15,13 +15,13 @@
*******************************************************************************/
package org.eclipse.pde.internal.genericeditor.target.extension.autocomplete.processors;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

import org.eclipse.equinox.p2.metadata.IVersionedId;
import org.eclipse.jface.text.contentassist.CompletionProposal;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.pde.internal.genericeditor.target.extension.autocomplete.InstallableUnitProposal;
import org.eclipse.pde.internal.genericeditor.target.extension.autocomplete.TargetDefinitionContentAssist;
import org.eclipse.pde.internal.genericeditor.target.extension.model.ITargetConstants;
Expand All @@ -30,7 +30,6 @@
import org.eclipse.pde.internal.genericeditor.target.extension.model.RepositoryCache;
import org.eclipse.pde.internal.genericeditor.target.extension.model.UnitNode;
import org.eclipse.pde.internal.genericeditor.target.extension.model.xml.Parser;
import org.osgi.framework.Version;

/**
* Class that computes autocompletions for attribute values. Example:
Expand Down Expand Up @@ -80,82 +79,49 @@ public ICompletionProposal[] getCompletionProposals() {
}
if (ITargetConstants.UNIT_ID_ATTR.equalsIgnoreCase(acKey)) {
if (node != null) {
if (!(node.getParentNode() instanceof LocationNode))
if (!(node.getParentNode() instanceof LocationNode location)) {
return getErrorCompletion();
LocationNode location = (LocationNode) node.getParentNode();
String repoLocation = location.getRepositoryLocation();
if (repoLocation == null) {
}
List<String> repoLocations = location.getRepositoryLocations();
if (repoLocations.isEmpty()) {
return getErrorCompletion();
}
RepositoryCache cache = RepositoryCache.getDefault();
List<UnitNode> units = cache.fetchP2UnitsFromRepo(repoLocation, false);
return convertToProposals(units);
Map<String, List<IVersionedId>> units = RepositoryCache.fetchP2UnitsFromRepos(repoLocations);
return toProposals(units.keySet().stream());
}

}

if (ITargetConstants.UNIT_VERSION_ATTR.equalsIgnoreCase(acKey)) {
if (node != null) {
if (!(node.getParentNode() instanceof LocationNode))
if (!(node.getParentNode() instanceof LocationNode location)) {
return getErrorCompletion();
LocationNode location = (LocationNode) node.getParentNode();
String repoLocation = location.getRepositoryLocation();
if (repoLocation == null) {
}
List<String> repoLocations = location.getRepositoryLocations();
if (repoLocations.isEmpty()) {
return getErrorCompletion();
}
RepositoryCache cache = RepositoryCache.getDefault();
List<UnitNode> repositoryUnits = cache.fetchP2UnitsFromRepo(repoLocation, false);
List<String> versions = null;
for (UnitNode unit : repositoryUnits) {
if (unit.getId().equals(node.getId())) {
versions = unit.getAvailableVersions();
}
Map<String, List<IVersionedId>> units = RepositoryCache.fetchP2UnitsFromRepos(repoLocations);
List<IVersionedId> versions = units.get(node.getId());
if (versions != null) {
Stream<String> availableVersions = Stream.concat(
versions.stream().map(unit -> unit.getVersion().toString()),
Stream.of(ITargetConstants.UNIT_VERSION_ATTR_GENERIC));
return toProposals(availableVersions.distinct());
}
if (versions != null)
return convertToVersionProposals(versions);

}

}

return new ICompletionProposal[] {};
}

private ICompletionProposal[] convertToVersionProposals(List<String> versions) {
List<String> dest = new ArrayList<>();
dest.addAll(versions);
Collections.sort(dest, (v1, v2) -> (new Version(v2)).compareTo(new Version(v1)));
if (!versions.contains(ITargetConstants.UNIT_VERSION_ATTR_GENERIC)) {
dest.add(ITargetConstants.UNIT_VERSION_ATTR_GENERIC);
}

List<ICompletionProposal> result = new ArrayList<>();
for (String version : dest) {
StyledString displayString = TargetDefinitionContentAssist.getFilteredStyledString(version, searchTerm);
if (displayString == null || displayString.length() == 0) {
continue;
}
result.add(new InstallableUnitProposal(displayString, offset - searchTerm.length(), searchTerm.length()));
}
return result.toArray(new ICompletionProposal[result.size()]);
}

private ICompletionProposal[] convertToProposals(List<UnitNode> units) {
Collections.sort(units, (node1, node2) -> String.CASE_INSENSITIVE_ORDER.compare(node1.getId(), node2.getId()));
List<ICompletionProposal> result = new ArrayList<>();
for (UnitNode unit : units) {
StyledString displayString = TargetDefinitionContentAssist.getFilteredStyledString(unit.getId(),
searchTerm);
if (displayString == null || displayString.length() == 0) {
continue;
}
result.add(new InstallableUnitProposal(displayString, offset - searchTerm.length(), searchTerm.length()));
}
return result.toArray(new ICompletionProposal[result.size()]);
private ICompletionProposal[] toProposals(Stream<String> values) {
return values.map(value -> TargetDefinitionContentAssist.getFilteredStyledString(value, searchTerm))
.filter(displayString -> displayString != null && !displayString.isEmpty())
.map(string -> new InstallableUnitProposal(string, offset - searchTerm.length(), searchTerm.length()))
.toArray(ICompletionProposal[]::new);
}

private ICompletionProposal[] getErrorCompletion() {

String replacementString = Messages.AttributeValueCompletionProcessor_RepositoryRequired;
return new ICompletionProposal[] {
new CompletionProposal("", offset, 0, 0, null, replacementString, null, null) }; //$NON-NLS-1$
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@
*******************************************************************************/
package org.eclipse.pde.internal.genericeditor.target.extension.command;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

import javax.xml.stream.XMLStreamException;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.equinox.p2.metadata.IVersionedId;
import org.eclipse.jface.dialogs.IPageChangeProvider;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.text.IDocument;
Expand All @@ -32,14 +32,12 @@
import org.eclipse.pde.internal.genericeditor.target.extension.model.RepositoryCache;
import org.eclipse.pde.internal.genericeditor.target.extension.model.UnitNode;
import org.eclipse.pde.internal.genericeditor.target.extension.model.xml.Parser;
import org.eclipse.pde.internal.genericeditor.target.extension.p2.UpdateJob;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;
import org.osgi.framework.Version;

public class UpdateUnitVersions extends AbstractHandler {

Expand Down Expand Up @@ -69,22 +67,21 @@ public Object execute(ExecutionEvent event) throws ExecutionException {

int offsetChange = 0;
String documentText = document.get();
for (Node n1 : locationsNode.get(0).getChildNodesByTag(ITargetConstants.LOCATION_TAG)) {
LocationNode locationNode = (LocationNode) n1;
String repositoryLocation = locationNode.getRepositoryLocation();
if (repositoryLocation == null) {

List<LocationNode> locationNodes = locationsNode.get(0).getChildNodesByTag(ITargetConstants.LOCATION_TAG)
.stream().map(LocationNode.class::cast).toList();

// Fetch all repos at once to fetch pending metadata in parallel
locationNodes.stream().map(LocationNode::getRepositoryLocations).flatMap(List::stream)
.forEach(RepositoryCache::prefetchP2MetadataOfRepository);

for (LocationNode locationNode : locationNodes) {
List<String> repositoryLocations = locationNode.getRepositoryLocations();
if (repositoryLocations.isEmpty()) {
continue;
}
RepositoryCache cache = RepositoryCache.getDefault();
if (!cache.isUpToDate(repositoryLocation)) {
try {
updateCache(locationNode);
} catch (InterruptedException e) {
e.printStackTrace();
continue;
}
}
List<UnitNode> repositoryUnits = cache.fetchP2UnitsFromRepo(repositoryLocation, false);
Map<String, List<IVersionedId>> repositoryUnits = RepositoryCache
.fetchP2UnitsFromRepos(repositoryLocations);
for (Node n2 : locationNode.getChildNodesByTag(ITargetConstants.UNIT_TAG)) {
UnitNode unitNode = ((UnitNode) n2);
String declaredVersion = unitNode.getVersion();
Expand All @@ -96,19 +93,12 @@ public Object execute(ExecutionEvent event) throws ExecutionException {
if (declaredVersion == null || !isValidExplicitVersion) {
continue;
}
List<String> versions = null;
for (UnitNode unit : repositoryUnits) {
if (unit.getId().equals(unitNode.getId())) {
versions = unit.getAvailableVersions();
break;
}
}
List<IVersionedId> versions = repositoryUnits.get(unitNode.getId());
if (versions == null || versions.isEmpty()) {
continue;
}
Collections.sort(versions, (v1, v2) -> (new Version(v2)).compareTo(new Version(v1)));
String version = versions.get(0);
if (version == null || version.isEmpty() || version.equals(declaredVersion)) {
String version = versions.get(0).getVersion().toString();
if (version.isEmpty() || version.equals(declaredVersion)) {
continue;
}

Expand Down Expand Up @@ -136,24 +126,14 @@ public Object execute(ExecutionEvent event) throws ExecutionException {
});
}

private void updateCache(LocationNode locationNode) throws InterruptedException {
Job job = new UpdateJob(locationNode);
job.setUser(true);
job.schedule();
while (job.getResult() == null) {
Thread.sleep(50);
}
}

private IDocument getDocument() {
IEditorPart editor = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
IDocumentProvider provider = null;
if (editor instanceof ITextEditor) {
provider = ((ITextEditor) editor).getDocumentProvider();
} else if (editor instanceof IPageChangeProvider) {
Object selectedPage = ((IPageChangeProvider) editor).getSelectedPage();
if (selectedPage instanceof ITextEditor) {
provider = ((ITextEditor) selectedPage).getDocumentProvider();
if (editor instanceof ITextEditor textEditor) {
provider = textEditor.getDocumentProvider();
} else if (editor instanceof IPageChangeProvider pageChangeProvider) {
if (pageChangeProvider.getSelectedPage() instanceof ITextEditor textEditor) {
provider = textEditor.getDocumentProvider();
}
}
if(provider == null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2016, 2017 Red Hat Inc. and others
* Copyright (c) 2016, 2024 Red Hat Inc. and others
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
Expand All @@ -14,19 +14,24 @@
*******************************************************************************/
package org.eclipse.pde.internal.genericeditor.target.extension.model;

import java.util.ArrayList;
import java.util.List;

/**
* Models the &lt;location&gt; nodes
*/
public class LocationNode extends Node {

private String repositoryLocation;
private List<String> repositoryLocations = new ArrayList<>();

public String getRepositoryLocation() {
return repositoryLocation;
public List<String> getRepositoryLocations() {
return repositoryLocations;
}

public void setRepositoryLocation(String repositoryLocation) {
this.repositoryLocation = repositoryLocation;
public void addRepositoryLocation(String repositoryLocation) {
if (repositoryLocation != null) {
this.repositoryLocations.add(repositoryLocation);
}
}

}
Loading
Loading