Skip to content

Commit

Permalink
Merge pull request #221 from OpenLiberty/4q2023
Browse files Browse the repository at this point in the history
Merge 4q2023 into main
  • Loading branch information
dshimo authored Oct 10, 2023
2 parents 634d1cd + a54e345 commit 07e9cc2
Show file tree
Hide file tree
Showing 58 changed files with 43,401 additions and 42,309 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ jobs:
java-version: 17
- name: Build LCLS
working-directory: ./liberty-ls
run: ./mvnw clean package
run: ./mvnw clean package -ntp -DskipTests
- name: Test LCLS
working-directory: ./liberty-ls
run: ./mvnw verify
run: ./mvnw verify -ntp
lemminx-liberty:
runs-on: ${{ matrix.os }}
strategy:
Expand All @@ -39,7 +39,7 @@ jobs:
java-version: 17
- name: Build Lemminx Liberty
working-directory: ./lemminx-liberty
run: ./mvnw clean package
run: ./mvnw clean package -ntp -DskipTests
- name: Test Lemminx Liberty
working-directory: ./lemminx-liberty
run: ./mvnw verify
run: ./mvnw verify -ntp
11 changes: 10 additions & 1 deletion lemminx-liberty/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<groupId>io.openliberty.tools</groupId>
<artifactId>liberty-langserver-lemminx</artifactId>
<packaging>jar</packaging>
<version>2.0.2-SNAPSHOT</version>
<version>2.1-SNAPSHOT</version>

<name>lemminx-liberty</name>
<url>https://github.com/OpenLiberty/liberty-language-server</url>
Expand Down Expand Up @@ -55,6 +55,15 @@
<target>17</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.1.2</version>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.1.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
package io.openliberty.tools.test;

import static org.eclipse.lemminx.XMLAssert.r;

import java.util.List;
import java.util.Set;
import java.util.HashSet;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.lang.StringBuilder;

import org.eclipse.lemminx.XMLAssert;
import org.eclipse.lemminx.commons.BadLocationException;
import org.eclipse.lsp4j.CompletionItem;

import org.eclipse.lsp4j.CompletionList;
import org.eclipse.lsp4j.WorkspaceFolder;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -93,7 +94,7 @@ public void testGetFeatures() throws BadLocationException {
String serverXML2 = String.join(newLine, //
"<server description=\"Sample Liberty server\">", //
" <featureManager>", //
" <feature>cdi-|</feature>", //
" <feature>cdi-5.0|</feature>", //
" <feature>servlet-3.1</feature>", //
" </featureManager>", //
"</server>" //
Expand All @@ -103,7 +104,33 @@ public void testGetFeatures() throws BadLocationException {
CompletionItem cdiCompletion3 = c("cdi-3.0", "cdi-3.0");
CompletionItem cdiCompletion4 = c("cdi-4.0", "cdi-4.0");

XMLAssert.testCompletionFor(serverXML2, null, serverXmlFile.toURI().toString(), TOTAL_ITEMS, cdiCompletion1, cdiCompletion2, cdiCompletion3, cdiCompletion4);
Set<String> cdiFeatures = new HashSet<String> ();
cdiFeatures.add("cdi-1.2");
cdiFeatures.add("cdi-2.0");
cdiFeatures.add("cdi-3.0");
cdiFeatures.add("cdi-4.0");

// changed to only return features that contain the passed in partial feature name (Note: if a version was listed after the hyphen, it gets stripped off in order to match all available versions of a feature)
// - includes the four cdi features and two random completion items with labels "<![CDATA[" and "<!--"
CompletionList completionList = XMLAssert.testCompletionFor(serverXML2, null, serverXmlFile.toURI().toString(), 6, cdiCompletion1, cdiCompletion2, cdiCompletion3, cdiCompletion4);

Set<String> foundLabels = new HashSet<String> ();
Set<String> unexpectedLabels = new HashSet<String> ();
StringBuilder sbGood = new StringBuilder();
StringBuilder sbBad = new StringBuilder();

for (CompletionItem nextItem : completionList.getItems()) {
if (!cdiFeatures.contains(nextItem.getLabel())) {
unexpectedLabels.add(nextItem.getLabel());
sbBad.append(nextItem.getLabel()+", ");
} else {
foundLabels.add(nextItem.getLabel());
sbGood.append(nextItem.getLabel());
}
}

org.junit.jupiter.api.Assertions.assertTrue(foundLabels.size() == 4, "Did not find all 4 expected labels: "+sbGood.toString());
//org.junit.jupiter.api.Assertions.assertTrue(unexpectedLabels.size() == 0, "Found unexpected completion items with labels "+sbBad.toString());

org.junit.jupiter.api.Assertions.assertTrue(featurelistFile.exists(), "Did not find generated featurelist file: "+featureListName);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
<artifactId>openliberty-kernel</artifactId>
<version>22.0.0.12</version>
</runtimeArtifact>
<configDirectory>src/test/resources</configDirectory>
</configuration>
<executions>
<execution>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2022 IBM Corporation and others.
* Copyright (c) 2022, 2023 IBM Corporation and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand All @@ -24,8 +24,10 @@
import org.eclipse.lsp4j.jsonrpc.CancelChecker;

import io.openliberty.tools.langserver.lemminx.codeactions.AddAttribute;
import io.openliberty.tools.langserver.lemminx.codeactions.AddFeature;
import io.openliberty.tools.langserver.lemminx.codeactions.CreateFile;
import io.openliberty.tools.langserver.lemminx.codeactions.EditAttribute;
import io.openliberty.tools.langserver.lemminx.codeactions.ReplaceFeature;

public class LibertyCodeActionParticipant implements ICodeActionParticipant {

Expand Down Expand Up @@ -53,6 +55,8 @@ private void registerCodeActions() {
codeActionParticipants.put(LibertyDiagnosticParticipant.MISSING_FILE_CODE, new CreateFile());
codeActionParticipants.put(LibertyDiagnosticParticipant.NOT_OPTIONAL_CODE, new EditAttribute());
codeActionParticipants.put(LibertyDiagnosticParticipant.IMPLICIT_NOT_OPTIONAL_CODE, new AddAttribute());
codeActionParticipants.put(LibertyDiagnosticParticipant.INCORRECT_FEATURE_CODE, new ReplaceFeature());
codeActionParticipants.put(LibertyDiagnosticParticipant.MISSING_CONFIGURED_FEATURE_CODE, new AddFeature());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import org.eclipse.lemminx.commons.BadLocationException;
import org.eclipse.lemminx.dom.DOMDocument;
Expand Down Expand Up @@ -56,14 +55,21 @@ public void onXMLContent(ICompletionRequest request, ICompletionResponse respons
// if the parent element of cursor is a <feature>
// provide the liberty features as completion options
if (parentElement.getTagName().equals(LibertyConstants.FEATURE_ELEMENT)) {
List<String> existingFeatures = new ArrayList<>();
// narrow down completion list based on what was already entered
DOMNode featureTextNode = (DOMNode) parentElement.getChildNodes().item(0);
String featureName = featureTextNode != null ? featureTextNode.getTextContent() : null;

// collect existing features
List<String> existingFeatures = new ArrayList<String>();
DOMNode featureMgrNode = null;
if (parentElement.getParentNode() != null
&& parentElement.getParentNode().getNodeName().equals(LibertyConstants.FEATURE_MANAGER_ELEMENT)) {
existingFeatures = collectExistingFeatures(parentElement.getParentNode());
featureMgrNode = parentElement.getParentNode();
existingFeatures = FeatureService.getInstance().collectExistingFeatures(parentElement.getParentNode(), featureName);
}

List<CompletionItem> featureCompletionItems = buildCompletionItems(parentElement, request.getXMLDocument(),
existingFeatures);
existingFeatures, featureName, featureMgrNode);
featureCompletionItems.stream().forEach(item -> response.addCompletionItem(item));
}
}
Expand All @@ -87,34 +93,53 @@ private CompletionItem buildFeatureCompletionItem(Feature feature, DOMElement fe
}

private List<CompletionItem> buildCompletionItems(DOMElement featureElement, DOMDocument domDocument,
List<String> existingFeatures) {
List<String> existingFeatures, String featureName, DOMNode featureMgrNode) {

LibertyRuntime runtimeInfo = LibertyUtils.getLibertyRuntimeInfo(domDocument);
String libertyVersion = runtimeInfo == null ? null : runtimeInfo.getRuntimeVersion();
String libertyRuntime = runtimeInfo == null ? null : runtimeInfo.getRuntimeType();

final int requestDelay = SettingsService.getInstance().getRequestDelay();
List<Feature> features = FeatureService.getInstance().getFeatures(libertyVersion, libertyRuntime, requestDelay, domDocument.getDocumentURI());

// filter out features that are already specified in the featureManager block
List<CompletionItem> uniqueFeatureCompletionItems = features.stream()
.filter(feature -> !existingFeatures.contains(feature.getWlpInformation().getShortName()))
.map(feat -> buildFeatureCompletionItem(feat, featureElement, domDocument)).collect(Collectors.toList());
boolean checkFeatureName = featureName != null && !featureName.isBlank();

if (checkFeatureName) {
String featureNameLowerCase = featureName.toLowerCase();

// strip off version number after the - so that we can provide all possible valid versions of a feature for completion
String featureNameToCompare = featureNameLowerCase.contains("-") ? featureNameLowerCase.substring(0, featureNameLowerCase.lastIndexOf("-")+1) : featureNameLowerCase;

List<Feature> completionFeatures = FeatureService.getInstance().getFeatureReplacements(featureNameToCompare, featureMgrNode, libertyVersion, libertyRuntime, requestDelay, domDocument.getDocumentURI());
return getFeatureCompletionItems(featureElement, domDocument, completionFeatures);
} else {
List<Feature> features = FeatureService.getInstance().getFeatures(libertyVersion, libertyRuntime, requestDelay, domDocument.getDocumentURI());
return getUniqueFeatureCompletionItems(featureElement, domDocument, features, existingFeatures);
}
}

private List<CompletionItem> getFeatureCompletionItems(DOMElement featureElement, DOMDocument domDocument, List<Feature> completionFeatures) {
List<CompletionItem> uniqueFeatureCompletionItems = new ArrayList<CompletionItem>();

for (Feature nextFeature : completionFeatures) {
CompletionItem ci = buildFeatureCompletionItem(nextFeature, featureElement, domDocument);
uniqueFeatureCompletionItems.add(ci);
}

return uniqueFeatureCompletionItems;
}

private List<String> collectExistingFeatures(DOMNode featureManager) {
List<String> includedFeatures = new ArrayList<>();
List<DOMNode> features = featureManager.getChildren();
for (DOMNode featureNode : features) {
DOMNode featureTextNode = (DOMNode) featureNode.getChildNodes().item(0);
// skip nodes that do not have any text value (ie. comments)
if (featureNode.getNodeName().equals(LibertyConstants.FEATURE_ELEMENT) && featureTextNode != null) {
String featureName = featureTextNode.getTextContent();
includedFeatures.add(featureName);
private List<CompletionItem> getUniqueFeatureCompletionItems(DOMElement featureElement, DOMDocument domDocument, List<Feature> allFeatures, List<String> existingFeatureNames) {
List<CompletionItem> uniqueFeatureCompletionItems = new ArrayList<CompletionItem>();

for (Feature nextFeature : allFeatures) {
String nextFeatureName = nextFeature.getWlpInformation().getShortName().toLowerCase();
if (!existingFeatureNames.contains(nextFeatureName)) {
CompletionItem ci = buildFeatureCompletionItem(nextFeature, featureElement, domDocument);
uniqueFeatureCompletionItems.add(ci);
}
}
return includedFeatures;

return uniqueFeatureCompletionItems;
}

}
Loading

0 comments on commit 07e9cc2

Please sign in to comment.