Skip to content

Commit

Permalink
Filter for Java (server) snippet
Browse files Browse the repository at this point in the history
Fixes redhat-developer#265

Signed-off-by: azerr <azerr@redhat.com>
  • Loading branch information
angelozerr committed Apr 8, 2020
1 parent ce8ff78 commit f71b085
Show file tree
Hide file tree
Showing 21 changed files with 446 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
*******************************************************************************/
package com.redhat.microprofile.commons;

import java.util.List;

/**
* MicroProfile Java Project labels
*
Expand All @@ -21,6 +23,8 @@ public class MicroProfileJavaProjectLabelsParams {

private String uri;

private List<String> types;

/**
* Returns the Java file uri.
*
Expand All @@ -38,4 +42,28 @@ public String getUri() {
public void setUri(String uri) {
this.uri = uri;
}

/**
* Returns the Java types list to check.
*
* <p>
* If the owner Java project of the Java file URI contains some type in the
* classpath, it will return the type as label in
* {@link ProjectLabelInfoEntry#getLabels()}
* </p>
*
* @return the Java types list to check
*/
public List<String> getTypes() {
return types;
}

/**
* Set the Java types list to check.
*
* @param types the Java types list to check.
*/
public void setTypes(List<String> types) {
this.types = types;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import com.redhat.microprofile.commons.ProjectLabelInfoEntry;
import com.redhat.microprofile.jdt.core.utils.IJDTUtils;
import com.redhat.microprofile.jdt.core.utils.JDTMicroProfileUtils;
import com.redhat.microprofile.jdt.core.utils.JDTTypeUtils;
import com.redhat.microprofile.jdt.internal.core.ProjectLabelRegistry;

/**
Expand Down Expand Up @@ -54,7 +55,7 @@ public List<ProjectLabelInfoEntry> getProjectLabelInfo() {
IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();

for (IProject project : projects) {
ProjectLabelInfoEntry info = getProjectLabelInfo(project);
ProjectLabelInfoEntry info = getProjectLabelInfo(project, null);
if (info != null) {
results.add(info);
}
Expand All @@ -66,12 +67,13 @@ public List<ProjectLabelInfoEntry> getProjectLabelInfo() {
* Returns project label results for the given Eclipse project.
*
* @param project Eclipse project.
* @param types the Java type list to check.
* @return project label results for the given Eclipse project.
*/
private ProjectLabelInfoEntry getProjectLabelInfo(IProject project) {
private ProjectLabelInfoEntry getProjectLabelInfo(IProject project, List<String> types) {
String uri = JDTMicroProfileUtils.getProjectURI(project);
if (uri != null) {
return new ProjectLabelInfoEntry(uri, getProjectLabels(project));
return new ProjectLabelInfoEntry(uri, getProjectLabels(project, types));
}
return null;
}
Expand All @@ -91,21 +93,40 @@ public ProjectLabelInfoEntry getProjectLabelInfo(MicroProfileJavaProjectLabelsPa
// The uri doesn't belong to an Eclipse project
return ProjectLabelInfoEntry.EMPTY_PROJECT_INFO;
}
return getProjectLabelInfo(file.getProject());
return getProjectLabelInfo(file.getProject(), params.getTypes());
}

private List<String> getProjectLabels(IProject project) {
/**
* Returns the project labels for the given project.
*
* @param project the Eclipse project.
* @param types the Java type list to check.
* @return the project labels for the given project.
*/
private List<String> getProjectLabels(IProject project, List<String> types) {
IJavaProject javaProject = JavaCore.create(project);

if (javaProject == null) {
return Collections.emptyList();
}

// Update labels by using the
// "com.redhat.microprofile.jdt.core.projectLabelProviders" extension point (ex
// : "maven", "gradle", "quarkus", "microprofile").
List<String> projectLabels = new ArrayList<>();
List<ProjectLabelDefinition> definitions = ProjectLabelRegistry.getInstance().getProjectLabelDefinitions();
for (ProjectLabelDefinition definition : definitions) {
projectLabels.addAll(definition.getProjectLabels(javaProject));
}
// Update labels by checking if some Java types are in the classpath of the Java
// project.
if (types != null) {
for (String type : types) {
if (JDTTypeUtils.findType(javaProject, type) != null) {
projectLabels.add(type);
}
}
}

return projectLabels;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import static com.redhat.microprofile.jdt.internal.core.ls.ArgumentUtils.getFirst;
import static com.redhat.microprofile.jdt.internal.core.ls.ArgumentUtils.getString;
import static com.redhat.microprofile.jdt.internal.core.ls.ArgumentUtils.getStringList;

import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -57,8 +58,10 @@ private static Object getProjectLabelInfo(List<Object> arguments, String command
"Command '%s' must be called with required MicroProfileJavaProjectLabelsParams.uri (java file URI)!",
commandId));
}
List<String> types = getStringList(obj, "types");
MicroProfileJavaProjectLabelsParams params = new MicroProfileJavaProjectLabelsParams();
params.setUri(javaFileUri);
params.setTypes(types);
return ProjectLabelManager.getInstance().getProjectLabelInfo(params, JDTUtilsLSImpl.getInstance(), monitor);
}
}
24 changes: 20 additions & 4 deletions microprofile.ls/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,23 +62,39 @@ Java and properties completion snippets are managed by the MicroProfile LS (snip

The `"context"` key can be provided to specify the condition in which the snippet should appear:

* for `properties files`: the context/extension can be declared in the snippet to show the snippet only if the extension belongs to the project.
* for `properties files`: the context/dependency can be declared in the snippet to show the snippet only if the extension belongs to the project.

```json
"Add datasource properties": {
"Add datasource properties": {
"prefix": "qds",
"body": [
...
],
"context": {
"extension": "quarkus-agroal"
"dependency": "quarkus-agroal"
}
}
```

means that the snippet is shown only if the project has the `quarkus-agroal` dependency.

* for `Java files` (not available for the moment)
* for `Java files`: the context/type can be declared in the snippet to show the snippet only if the Java type belongs to the project.

```json
"@Operation": {
"prefix": [
"@Operation"
],
"body": [
...
],
"context": {
"type": "org.eclipse.microprofile.openapi.annotations.Operation"
}
}
```

means that the snippet is shown only if the project has the `org.eclipse.microprofile.openapi.annotations.Operation` Java Annotation in the classpath. In otherwords, only when the Java project have a dependency to the MicroProfile Open API.

## Adding new internal snippets

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
*******************************************************************************/
package com.redhat.microprofile.commons;

import java.util.List;

/**
* MicroProfile Java Project labels
*
Expand All @@ -21,6 +23,8 @@ public class MicroProfileJavaProjectLabelsParams {

private String uri;

private List<String> types;

/**
* Returns the Java file uri.
*
Expand All @@ -38,4 +42,28 @@ public String getUri() {
public void setUri(String uri) {
this.uri = uri;
}

/**
* Returns the Java types list to check.
*
* <p>
* If the owner Java project of the Java file URI contains some type in the
* classpath, it will return the type as label in
* {@link ProjectLabelInfoEntry#getLabels()}
* </p>
*
* @return the Java types list to check
*/
public List<String> getTypes() {
return types;
}

/**
* Set the Java types list to check.
*
* @param types the Java types list to check.
*/
public void setTypes(List<String> types) {
this.types = types;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
import com.redhat.microprofile.ls.commons.snippets.TextDocumentSnippetRegistry;
import com.redhat.microprofile.settings.MicroProfileCodeLensSettings;
import com.redhat.microprofile.settings.SharedSettings;
import com.redhat.microprofile.snippets.LanguageId;
import com.redhat.microprofile.snippets.SnippetContextForJava;

/**
* LSP text document service for Java file.
Expand All @@ -80,7 +80,8 @@ public JavaTextDocumentService(MicroProfileLanguageServer microprofileLanguageSe
this.documents = new JavaTextDocuments(microprofileLanguageServer);
}

// ------------------------------ did* for Java file ------------------------------
// ------------------------------ did* for Java file
// ------------------------------

@Override
public void didOpen(DidOpenTextDocumentParams params) {
Expand Down Expand Up @@ -110,32 +111,31 @@ public void didSave(DidSaveTextDocumentParams params) {

@Override
public CompletableFuture<Either<List<CompletionItem>, CompletionList>> completion(CompletionParams params) {
return CompletableFutures.computeAsync(cancel -> {
try {
// Returns java snippets
TextDocument document = documents.get(params.getTextDocument().getUri());
int completionOffset = document.offsetAt(params.getPosition());
boolean canSupportMarkdown = true;
CompletionList list = new CompletionList();
list.setItems(new ArrayList<>());
getSnippetRegistry().getCompletionItems(document, completionOffset, canSupportMarkdown, context -> {
return true;
}).forEach(item -> {
list.getItems().add(item);
});
return Either.forRight(list);
} catch (BadLocationException e) {
LOGGER.log(Level.SEVERE, "Error while getting java completions", e);
return Either.forRight(null);
}
});
}

private TextDocumentSnippetRegistry getSnippetRegistry() {
if (snippetRegistry == null) {
snippetRegistry = new TextDocumentSnippetRegistry(LanguageId.java.name());
}
return snippetRegistry;
JavaTextDocument document = documents.get(params.getTextDocument().getUri());
return document.executeIfInMicroProfileProject((projectInfo) -> {
return CompletableFutures.computeAsync(cancel -> {
try {
// Returns java snippets
int completionOffset = document.offsetAt(params.getPosition());
boolean canSupportMarkdown = true;
CompletionList list = new CompletionList();
list.setItems(new ArrayList<>());
documents.getSnippetRegistry()
.getCompletionItems(document, completionOffset, canSupportMarkdown, context -> {
if (context != null && context instanceof SnippetContextForJava) {
return ((SnippetContextForJava) context).isMatch(projectInfo);
}
return true;
}).forEach(item -> {
list.getItems().add(item);
});
return Either.forRight(list);
} catch (BadLocationException e) {
LOGGER.log(Level.SEVERE, "Error while getting java completions", e);
return Either.forRight(null);
}
});
}, Either.forRight(null));
}

// ------------------------------ Code Lens ------------------------------
Expand All @@ -152,7 +152,7 @@ public CompletableFuture<List<? extends CodeLens>> codeLens(CodeLensParams param
return CompletableFuture.completedFuture(Collections.emptyList());
}
JavaTextDocument document = documents.get(params.getTextDocument().getUri());
return document.executeIfInMicroProfileProject(() -> {
return document.executeIfInMicroProfileProject((projectInfo) -> {
MicroProfileJavaCodeLensParams javaParams = new MicroProfileJavaCodeLensParams(
params.getTextDocument().getUri());
if (sharedSettings.getCommandCapabilities().isCommandSupported(CommandKind.COMMAND_OPEN_URI)) {
Expand All @@ -171,7 +171,7 @@ public CompletableFuture<List<? extends CodeLens>> codeLens(CodeLensParams param
@Override
public CompletableFuture<List<Either<Command, CodeAction>>> codeAction(CodeActionParams params) {
JavaTextDocument document = documents.get(params.getTextDocument().getUri());
return document.executeIfInMicroProfileProject(() -> {
return document.executeIfInMicroProfileProject((projectInfo) -> {
MicroProfileJavaCodeActionParams javaParams = new MicroProfileJavaCodeActionParams();
javaParams.setTextDocument(params.getTextDocument());
javaParams.setRange(params.getRange());
Expand All @@ -195,7 +195,7 @@ public CompletableFuture<List<Either<Command, CodeAction>>> codeAction(CodeActio
@Override
public CompletableFuture<Hover> hover(HoverParams params) {
JavaTextDocument document = documents.get(params.getTextDocument().getUri());
return document.executeIfInMicroProfileProject(() -> {
return document.executeIfInMicroProfileProject((projectinfo) -> {
boolean markdownSupported = sharedSettings.getHoverSettings().isContentFormatSupported(MarkupKind.MARKDOWN);
DocumentFormat documentFormat = markdownSupported ? DocumentFormat.Markdown : DocumentFormat.PlainText;
MicroProfileJavaHoverParams javaParams = new MicroProfileJavaHoverParams(params.getTextDocument().getUri(),
Expand All @@ -212,7 +212,7 @@ public CompletableFuture<Hover> hover(HoverParams params) {
* @param document the opened Java file.
*/
private void triggerValidationFor(JavaTextDocument document) {
document.executeIfInMicroProfileProject(() -> {
document.executeIfInMicroProfileProject((projectinfo) -> {
String uri = document.getUri();
triggerValidationFor(Arrays.asList(uri));
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.redhat.microprofile.ls;

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

import com.redhat.microprofile.ls.commons.snippets.Snippet;
import com.redhat.microprofile.ls.commons.snippets.TextDocumentSnippetRegistry;
import com.redhat.microprofile.snippets.LanguageId;
import com.redhat.microprofile.snippets.SnippetContextForJava;

public class JavaTextDocumentSnippetRegistry extends TextDocumentSnippetRegistry {

private List<String> types;

public JavaTextDocumentSnippetRegistry() {
super(LanguageId.java.name());
}

public List<String> getTypes() {
if (types != null) {
return types;
}
types = collectTypes();
return types;
}

private synchronized List<String> collectTypes() {
if (types != null) {
return types;
}
List<String> types = new ArrayList<>();
for (Snippet snippet : getSnippets()) {
if (snippet.getContext() != null && snippet.getContext() instanceof SnippetContextForJava) {
List<String> t = ((SnippetContextForJava) snippet.getContext()).getTypes();
if (t != null) {
types.addAll(t);
}
}
}
return types;
}
}
Loading

0 comments on commit f71b085

Please sign in to comment.