Merge branch 'master' into jdt-classpath
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.5-SNAPSHOT</version>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<relativePath>../commons/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.5-SNAPSHOT</version>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.5-SNAPSHOT</version>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.5-SNAPSHOT</version>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -76,8 +76,8 @@ public class GradleCore {
|
||||
*/
|
||||
((DefaultGradleConnector) gradleConnector).daemonMaxIdleTime(1, TimeUnit.SECONDS);
|
||||
configuration.configure(gradleConnector);
|
||||
// Use patched Gradle 4.3 distribution as a workaround for https://github.com/gradle/gradle/issues/2483
|
||||
gradleConnector.useDistribution(URI.create("http://s3-test.spring.io/sts4/custom-gradle-builds/gradle-4.3-build.zip"));
|
||||
// Use patched Gradle 4.4 distribution or higher as a workaround for https://github.com/gradle/gradle/issues/2483
|
||||
gradleConnector.useGradleVersion("4.6");
|
||||
connection = gradleConnector.connect();
|
||||
return connection.getModel(modelType);
|
||||
} catch (GradleConnectionException e) {
|
||||
|
||||
@@ -83,7 +83,7 @@ public class GradleProjectTest {
|
||||
@Test
|
||||
public void outputFolder() throws Exception {
|
||||
GradleJavaProject project = getGradleProject("test-app-1");
|
||||
assertTrue(project.getClasspath().getOutputFolder().endsWith("bin"));
|
||||
assertTrue(project.getClasspath().getOutputFolder().toString().contains("/bin"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.5-SNAPSHOT</version>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.5-SNAPSHOT</version>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016-2018 Pivotal, Inc.
|
||||
* Copyright (c) 2016, 2018 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -31,12 +31,14 @@ import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguage
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SortKeys;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
@@ -46,6 +48,8 @@ import reactor.core.scheduler.Schedulers;
|
||||
*/
|
||||
public class VscodeCompletionEngineAdapter implements VscodeCompletionEngine {
|
||||
|
||||
private static final Supplier<Logger> LOG = Suppliers.memoize(() -> LoggerFactory.getLogger(VscodeCompletionEngineAdapter.class));
|
||||
|
||||
public static class LazyCompletionResolver {
|
||||
private int nextId = 0; //Used to assign unique id to completion items.
|
||||
|
||||
@@ -64,7 +68,7 @@ public class VscodeCompletionEngineAdapter implements VscodeCompletionEngine {
|
||||
try {
|
||||
resolveItem(doc, completion, unresolved);
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
LOG.get().error("{}", e);
|
||||
}
|
||||
});
|
||||
return id;
|
||||
@@ -73,12 +77,12 @@ public class VscodeCompletionEngineAdapter implements VscodeCompletionEngine {
|
||||
public synchronized void resolveNow(CompletionItem unresolved) {
|
||||
Object id = unresolved.getData();
|
||||
if (id!=null) {
|
||||
Consumer<CompletionItem> resolver = resolvers.get(id);
|
||||
Consumer<CompletionItem> resolver = resolvers.get(id instanceof JsonPrimitive ? ((JsonPrimitive)id).getAsString() : id);
|
||||
if (resolver!=null) {
|
||||
resolver.accept(unresolved);
|
||||
unresolved.setData(null); //No longer needed after item is resolved.
|
||||
} else {
|
||||
Log.warn("Couldn't resolve completion item. Did it already get flushed from the resolver's cache? "+unresolved.getLabel());
|
||||
LOG.get().warn("Couldn't resolve completion item. Did it already get flushed from the resolver's cache? "+unresolved.getLabel());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -225,7 +229,7 @@ public class VscodeCompletionEngineAdapter implements VscodeCompletionEngine {
|
||||
return Optional.of(vscodeEdit);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
LOG.get().error("{}", e);
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
@@ -241,7 +245,7 @@ public class VscodeCompletionEngineAdapter implements VscodeCompletionEngine {
|
||||
return StringUtil.stripIndentation(refIndent, newText);
|
||||
}
|
||||
} catch (BadLocationException e) {
|
||||
Log.log(e);
|
||||
LOG.get().error("{}", e);
|
||||
}
|
||||
return newText;
|
||||
}
|
||||
|
||||
@@ -238,7 +238,6 @@ public class SimpleLanguageServer implements Sts4LanguageServer, LanguageClientA
|
||||
if (ih!=null){
|
||||
ih.accept(params);
|
||||
}
|
||||
Log.info("IntializeResult = {}");
|
||||
return CompletableFuture.completedFuture(result);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.5-SNAPSHOT</version>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.5-SNAPSHOT</version>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.5-SNAPSHOT</version>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.5-SNAPSHOT</version>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.5-SNAPSHOT</version>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>0.1.5-SNAPSHOT</version>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<name>commons-parent</name>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.5-SNAPSHOT</version>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<relativePath>../commons/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -401,8 +401,11 @@ public class PipelineYmlSchema implements YamlSchema {
|
||||
addProp(resourceType, "source", resourceSource);
|
||||
addProp(resourceType, "privileged", t_boolean);
|
||||
|
||||
YType t_group_name_def= f.yatomic("Group Name")
|
||||
.parseWith(ValueParsers.NE_STRING);
|
||||
|
||||
AbstractType group = f.ybean("Group");
|
||||
addProp(group, "name", t_ne_string).isPrimary(true);
|
||||
addProp(group, "name", t_group_name_def).isPrimary(true);
|
||||
addProp(group, "resources", f.yseq(t_resource_name));
|
||||
addProp(group, "jobs", f.yseq(t_job_name));
|
||||
|
||||
@@ -414,7 +417,8 @@ public class PipelineYmlSchema implements YamlSchema {
|
||||
definitionTypes = ImmutableList.of(
|
||||
jobNameDef,
|
||||
resourceTypeNameDef,
|
||||
t_resource_name_def
|
||||
t_resource_name_def,
|
||||
t_group_name_def
|
||||
);
|
||||
|
||||
initializeDefaultResourceTypes();
|
||||
|
||||
@@ -17,5 +17,5 @@ plan:
|
||||
get: string
|
||||
```
|
||||
|
||||
*Required.* The logical name of the resource being fetched. This name satisfies logical inputs to a [Task](https://concourse.ci/concepts.html#tasks), and may be referenced within the plan itself (e.g. in the `file` attribute of a `task` step).
|
||||
*Required.* The logical name of the resource being fetched. This name satisfies logical inputs to a [Task](https://concourse-ci.org/concepts.html#tasks), and may be referenced within the plan itself (e.g. in the `file` attribute of a `task` step).
|
||||
|
||||
|
||||
@@ -4,4 +4,4 @@ If set to `latest`, scheduling will just find the latest available version of a
|
||||
|
||||
If set to `every`, builds will walk through all available versions of the resource. Note that if `passed` is also configured, it will only step through the versions satisfying the constraints.
|
||||
|
||||
If set to a specific version (e.g. `{ref: abcdef123}`), only that version will be used. Note that the version must be available and detected by the resource, otherwise the input will never be satisfied. You may want to use [check-resource](https://concourse.ci/fly-check-resource.html) to force detection of resource versions, if you need to use an older one that was never detected (as all newly configured resources start from the latest version).
|
||||
If set to a specific version (e.g. `{ref: abcdef123}`), only that version will be used. Note that the version must be available and detected by the resource, otherwise the input will never be satisfied. You may want to use [check-resource](https://concourse-ci.org/fly-check-resource.html) to force detection of resource versions, if you need to use an older one that was never detected (as all newly configured resources start from the latest version).
|
||||
@@ -3,8 +3,8 @@ to the specified files are ignored.
|
||||
|
||||
Note that if you want to push commits that change these files via a `put`,
|
||||
the commit will still be "detected", as [`check` and `put` both introduce
|
||||
versions](https://concourse.ci/pipeline-mechanics.html#collecting-versions).
|
||||
versions](https://concourse-ci.org/pipeline-mechanics.html#collecting-versions).
|
||||
To avoid this you should define a second resource that you use for commits
|
||||
that change files that you don't want to feed back into your pipeline - think
|
||||
of one as read-only (with `ignore_paths`) and one as write-only (which
|
||||
shouldn't need it).
|
||||
shouldn't need it).
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
*Optional.* Password for HTTP(S) auth when pulling/pushing.
|
||||
|
||||
Note: You can also use pipeline templating to hide this password in source control. (For more information: https://concourse.ci/fly-set-pipeline.html)
|
||||
Note: You can also use pipeline templating to hide this password in source control. (For more information: https://concourse-ci.org/fly-set-pipeline.html)
|
||||
|
||||
@@ -9,4 +9,4 @@ Example:
|
||||
DWiJL+OFeg9kawcUL6hQ8JeXPhlImG6RTUffma9+iGQyyBMCGd1l
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
||||
Note: You can also use pipeline templating to hide this private key in source control. (For more information: https://concourse.ci/fly-set-pipeline.html)
|
||||
Note: You can also use pipeline templating to hide this private key in source control. (For more information: https://concourse-ci.org/fly-set-pipeline.html)
|
||||
|
||||
@@ -17,5 +17,5 @@ A simple grouping for the pipeline above may look like:
|
||||
|
||||
This would display two tabs at the top of the home page: "tests" and "deploy". Once you have added groups to your pipeline then all jobs must be in a group otherwise they will not be visible.
|
||||
|
||||
For a real world example of how groups can be used to simplify navigation and provide logical grouping, see the groups used at the top of the page in the [Concourse pipeline](https://ci.concourse.ci/).
|
||||
For a real world example of how groups can be used to simplify navigation and provide logical grouping, see the groups used at the top of the page in the [Concourse pipeline](https://ci.concourse-ci.org/).
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Pushes to the given [Resource](https://concourse.ci/concepts.html#resources).
|
||||
Pushes to the given [Resource](https://concourse-ci.org/concepts.html#resources).
|
||||
All artifacts collected during the plan's execution will be available in the working directory.
|
||||
|
||||
For example, the following plan fetches a repo using [get](https://concourse.ci/get-step.html) and pushes it to another repo (assuming `repo-develop` and `repo-master` are defined as `git` resources):
|
||||
For example, the following plan fetches a repo using [get](https://concourse-ci.org/get-step.html) and pushes it to another repo (assuming `repo-develop` and `repo-master` are defined as `git` resources):
|
||||
|
||||
```
|
||||
plan:
|
||||
@@ -34,4 +34,4 @@ plan:
|
||||
put: string
|
||||
```
|
||||
|
||||
Required. The logical name of the resource being pushed. The pushed resource will be available under this name after the push succeeds.
|
||||
Required. The logical name of the resource being pushed. The pushed resource will be available under this name after the push succeeds.
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
*Optional.* Defaults to `name`.
|
||||
|
||||
The resource to update, as configured in [resources](https://concourse.ci/configuring-resources.html).
|
||||
The resource to update, as configured in [resources](https://concourse-ci.org/configuring-resources.html).
|
||||
|
||||
@@ -1 +1 @@
|
||||
*Required.* The name of the resource. This should be short and simple. This name will be referenced by [build plans](https://concourse.ci/build-plans.html) of jobs in the pipeline.
|
||||
*Required.* The name of the resource. This should be short and simple. This name will be referenced by [build plans](https://concourse-ci.org/build-plans.html) of jobs in the pipeline.
|
||||
|
||||
@@ -19,4 +19,4 @@ The following example configures the task to use the `golang:1.6` Docker image:
|
||||
|
||||
You can use any resource that returns a filesystem in the correct format (a `/rootfs` directory and a `metadata.json` file in the top level) but normally this will be the [Docker Image resource](https://github.com/concourse/docker-image-resource). If you'd like to make a resource of your own that supports this please use that as a reference implementation for now.
|
||||
|
||||
If you want to use an artifact source within the plan containing an image, you must set the [image](https://concourse.ci/task-step.html#task-image) in the plan step instead.
|
||||
If you want to use an artifact source within the plan containing an image, you must set the [image](https://concourse-ci.org/task-step.html#task-image) in the plan step instead.
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
*Required.* The expected set of inputs for the task.
|
||||
|
||||
This determines which artifacts will propagate into the task, as the [build plan](https://concourse.ci/build-plans.html) executes. If any specified inputs are not present, the task will end with an error, without running.
|
||||
This determines which artifacts will propagate into the task, as the [build plan](https://concourse-ci.org/build-plans.html) executes. If any specified inputs are not present, the task will end with an error, without running.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
*Optional.* The artifacts produced by the task.
|
||||
|
||||
Each output configures a directory to make available to later steps in the [build plan](https://concourse.ci/build-plans.html). The directory will be automatically created before the task runs, and the task should place any artifacts it wants to export in the directory.
|
||||
Each output configures a directory to make available to later steps in the [build plan](https://concourse-ci.org/build-plans.html). The directory will be automatically created before the task runs, and the task should place any artifacts it wants to export in the directory.
|
||||
|
||||
For example, the following task and script would be used to propagate a built binary to later steps:
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Executes a [Task](https://concourse.ci/concepts.html#tasks), either from a file fetched via the preceding steps, or with inlined configuration.
|
||||
Executes a [Task](https://concourse-ci.org/concepts.html#tasks), either from a file fetched via the preceding steps, or with inlined configuration.
|
||||
|
||||
task: string
|
||||
|
||||
|
||||
@@ -3458,15 +3458,20 @@ public class ConcourseEditorTest {
|
||||
"- name: bar-resource\n" +
|
||||
"jobs:\n" +
|
||||
"- name: do-some-stuff\n" +
|
||||
"- name: do-more-stuff\n"
|
||||
"- name: do-more-stuff\n" +
|
||||
"groups:\n" +
|
||||
"- name: group-one\n" +
|
||||
"- name: group-two\n"
|
||||
);
|
||||
|
||||
editor.assertDocumentSymbols(
|
||||
editor.assertDocumentSymbols(
|
||||
"some-resource-type|ResourceType",
|
||||
"foo-resource|Resource",
|
||||
"bar-resource|Resource",
|
||||
"do-some-stuff|Job",
|
||||
"do-more-stuff|Job"
|
||||
"do-more-stuff|Job",
|
||||
"group-one|Group",
|
||||
"group-two|Group"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.5-SNAPSHOT</version>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<relativePath>../commons/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.1.5-SNAPSHOT</version>
|
||||
<version>0.1.6-SNAPSHOT</version>
|
||||
<relativePath>../commons/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public enum MediaTypeMapping {
|
||||
|
||||
ALL("*/*"),
|
||||
APPLICATION_ATOM_XML("application/atom+xml"),
|
||||
APPLICATION_FORM_URLENCODED("application/x-www-form-urlencoded"),
|
||||
APPLICATION_JSON("application/json"),
|
||||
APPLICATION_JSON_UTF8("application/json;charset=UTF-8"),
|
||||
APPLICATION_OCTET_STREAM("application/octet-stream"),
|
||||
APPLICATION_PDF("application/pdf"),
|
||||
APPLICATION_PROBLEM_JSON("application/problem+json"),
|
||||
APPLICATION_PROBLEM_JSON_UTF8("application/problem+json;charset=UTF-8"),
|
||||
APPLICATION_PROBLEM_XML("application/problem+xml"),
|
||||
APPLICATION_RSS_XML("application/rss+xml"),
|
||||
APPLICATION_STREAM_JSON("application/stream+json"),
|
||||
APPLICATION_XHTML_XML("application/xhtml+xml"),
|
||||
APPLICATION_XML("application/xml"),
|
||||
IMAGE_GIF("image/gif"),
|
||||
IMAGE_JPEG("image/jpeg"),
|
||||
IMAGE_PNG("image/png"),
|
||||
MULTIPART_FORM_DATA("multipart/form-data"),
|
||||
TEXT_EVENT_STREAM("text/event-stream"),
|
||||
TEXT_HTML("text/html"),
|
||||
TEXT_MARKDOWN("text/markdown"),
|
||||
TEXT_PLAIN("text/plain"),
|
||||
TEXT_XML("text/xml");
|
||||
|
||||
private String mediaType;
|
||||
|
||||
private MediaTypeMapping(String mediaType) {
|
||||
this.mediaType = mediaType;
|
||||
}
|
||||
|
||||
public String getMediaType() {
|
||||
return mediaType;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,8 +28,6 @@ import org.eclipse.jdt.core.dom.NormalAnnotation;
|
||||
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
|
||||
import org.eclipse.jdt.core.dom.TypeDeclaration;
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
import org.eclipse.lsp4j.SymbolKind;
|
||||
import org.springframework.ide.vscode.boot.java.Annotations;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider;
|
||||
@@ -48,9 +46,9 @@ public class RequestMappingSymbolProvider implements SymbolProvider {
|
||||
Location location = new Location(doc.getUri(), doc.toRange(node.getStartPosition(), node.getLength()));
|
||||
String[] path = getPath(node);
|
||||
String[] parentPath = getParentPath(node);
|
||||
String[] method = getMethod(node);
|
||||
|
||||
String methodStr = method == null || method.length == 0 ? "" : String.join(",", method);
|
||||
String[] methods = getMethod(node);
|
||||
String[] contentTypes = getContentTypes(node);
|
||||
String[] acceptTypes = getAcceptTypes(node);
|
||||
|
||||
return (parentPath == null ? Stream.of("") : Arrays.stream(parentPath)).filter(Objects::nonNull)
|
||||
.flatMap(parent -> (path == null ? Stream.<String>empty() : Arrays.stream(path))
|
||||
@@ -62,8 +60,7 @@ public class RequestMappingSymbolProvider implements SymbolProvider {
|
||||
}
|
||||
return resultPath.startsWith("/") ? resultPath : "/" + resultPath;
|
||||
}))
|
||||
.map(p -> "@" + p + (methodStr.isEmpty() ? "" : " -- " + methodStr))
|
||||
.map(symbolLabel -> new EnhancedSymbolInformation(new SymbolInformation(symbolLabel, SymbolKind.Interface, location), null))
|
||||
.map(p -> RouteUtils.createRouteSymbol(location, p, methods, contentTypes, acceptTypes, null))
|
||||
.collect(Collectors.toList());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -176,6 +173,44 @@ public class RequestMappingSymbolProvider implements SymbolProvider {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String[] getAcceptTypes(Annotation node) {
|
||||
if (node.isNormalAnnotation()) {
|
||||
NormalAnnotation normNode = (NormalAnnotation) node;
|
||||
List<?> values = normNode.values();
|
||||
for (Iterator<?> iterator = values.iterator(); iterator.hasNext();) {
|
||||
Object object = iterator.next();
|
||||
if (object instanceof MemberValuePair) {
|
||||
MemberValuePair pair = (MemberValuePair) object;
|
||||
String valueName = pair.getName().getIdentifier();
|
||||
if (valueName != null && valueName.equals("consumes")) {
|
||||
Expression expression = pair.getValue();
|
||||
return ASTUtils.getExpressionValueAsArray(expression);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
private String[] getContentTypes(Annotation node) {
|
||||
if (node.isNormalAnnotation()) {
|
||||
NormalAnnotation normNode = (NormalAnnotation) node;
|
||||
List<?> values = normNode.values();
|
||||
for (Iterator<?> iterator = values.iterator(); iterator.hasNext();) {
|
||||
Object object = iterator.next();
|
||||
if (object instanceof MemberValuePair) {
|
||||
MemberValuePair pair = (MemberValuePair) object;
|
||||
String valueName = pair.getName().getIdentifier();
|
||||
if (valueName != null && valueName.equals("produces")) {
|
||||
Expression expression = pair.getValue();
|
||||
return ASTUtils.getExpressionValueAsArray(expression);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<EnhancedSymbolInformation> getSymbols(TypeDeclaration typeDeclaration, TextDocument doc) {
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
import org.eclipse.lsp4j.SymbolKind;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class RouteUtils {
|
||||
|
||||
public static EnhancedSymbolInformation createRouteSymbol(Location location, String path,
|
||||
String[] httpMethods, String[] contentTypes, String[] acceptTypes, Object enhancedInformation) {
|
||||
|
||||
if (path != null && path.length() > 0) {
|
||||
String label = "@" + (path.startsWith("/") ? path : ("/" + path));
|
||||
label += (httpMethods == null || httpMethods.length == 0 ? "" : " -- " + WebfluxUtils.getStringRep(httpMethods, string -> string));
|
||||
|
||||
String acceptType = WebfluxUtils.getStringRep(acceptTypes, WebfluxUtils::getMediaType);
|
||||
label += acceptType != null ? " - Accept: " + acceptType : "";
|
||||
|
||||
String contentType = WebfluxUtils.getStringRep(contentTypes, WebfluxUtils::getMediaType);
|
||||
label += contentType != null ? " - Content-Type: " + contentType : "";
|
||||
|
||||
return new EnhancedSymbolInformation(new SymbolInformation(label, SymbolKind.Interface, location), enhancedInformation);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTVisitor;
|
||||
import org.eclipse.jdt.core.dom.IMethodBinding;
|
||||
import org.eclipse.jdt.core.dom.MethodInvocation;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class WebfluxAcceptTypeFinder extends ASTVisitor {
|
||||
|
||||
private Set<String> acceptTypes;
|
||||
|
||||
public WebfluxAcceptTypeFinder() {
|
||||
this.acceptTypes = new LinkedHashSet<>();
|
||||
}
|
||||
|
||||
public Set<String> getAcceptTypes() {
|
||||
return acceptTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MethodInvocation node) {
|
||||
IMethodBinding methodBinding = node.resolveMethodBinding();
|
||||
|
||||
if (WebfluxUtils.REQUEST_PREDICATES_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
|
||||
String name = methodBinding.getName();
|
||||
if (name != null && WebfluxUtils.REQUEST_PREDICATE_ACCEPT_TYPE_METHOD.equals(name)) {
|
||||
String acceptType = WebfluxUtils.extractSimpleNameArgument(node);
|
||||
if (acceptType != null) {
|
||||
acceptTypes.add(acceptType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return !WebfluxUtils.isRouteMethodInvocation(methodBinding);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.jdt.core.dom.ASTVisitor;
|
||||
import org.eclipse.jdt.core.dom.IMethodBinding;
|
||||
import org.eclipse.jdt.core.dom.MethodInvocation;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class WebfluxContentTypeFinder extends ASTVisitor {
|
||||
|
||||
private Set<String> contentTypes;
|
||||
private ASTNode root;
|
||||
|
||||
public WebfluxContentTypeFinder(ASTNode root) {
|
||||
this.root = root;
|
||||
this.contentTypes = new LinkedHashSet<>();
|
||||
}
|
||||
|
||||
public Set<String> getContentTypes() {
|
||||
return contentTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MethodInvocation node) {
|
||||
boolean visitChildren = true;
|
||||
|
||||
if (node != this.root) {
|
||||
IMethodBinding methodBinding = node.resolveMethodBinding();
|
||||
|
||||
if (WebfluxUtils.REQUEST_PREDICATES_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
|
||||
String name = methodBinding.getName();
|
||||
if (name != null && WebfluxUtils.REQUEST_PREDICATE_CONTENT_TYPE_METHOD.equals(name)) {
|
||||
String contentType = WebfluxUtils.extractSimpleNameArgument(node);
|
||||
if (contentType != null) {
|
||||
contentTypes.add(contentType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (WebfluxUtils.isRouteMethodInvocation(methodBinding)) {
|
||||
visitChildren = false;
|
||||
}
|
||||
}
|
||||
return visitChildren;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -71,7 +71,19 @@ public class WebfluxHandlerCodeLensProvider implements CodeLensProvider {
|
||||
|
||||
CodeLens codeLens = new CodeLens();
|
||||
codeLens.setRange(document.toRange(node.getName().getStartPosition(), node.getName().getLength()));
|
||||
codeLens.setCommand(new Command(handlerInfo.getSymbol(), null));
|
||||
|
||||
String httpMethod = WebfluxUtils.getStringRep(handlerInfo.getHttpMethods(), string -> string);
|
||||
String codeLensCommand = httpMethod != null ? httpMethod + " " : "";
|
||||
|
||||
codeLensCommand += handlerInfo.getPath();
|
||||
|
||||
String acceptType = WebfluxUtils.getStringRep(handlerInfo.getAcceptTypes(), WebfluxUtils::getMediaType);
|
||||
codeLensCommand += acceptType != null ? " - Accept: " + acceptType : "";
|
||||
|
||||
String contentType = WebfluxUtils.getStringRep(handlerInfo.getContentTypes(), WebfluxUtils::getMediaType);
|
||||
codeLensCommand += contentType != null ? " - Content-Type: " + contentType : "";
|
||||
|
||||
codeLens.setCommand(new Command(codeLensCommand, null));
|
||||
|
||||
resultAccumulator.add(codeLens);
|
||||
} catch (BadLocationException e) {
|
||||
@@ -81,5 +93,5 @@ public class WebfluxHandlerCodeLensProvider implements CodeLensProvider {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -15,18 +15,22 @@ package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
*/
|
||||
public class WebfluxHandlerInformation {
|
||||
|
||||
private final String symbol;
|
||||
private String handlerClass;
|
||||
private String handlerMethod;
|
||||
private final String handlerClass;
|
||||
private final String handlerMethod;
|
||||
|
||||
public WebfluxHandlerInformation(String symbol, String handlerClass, String handlerMethod) {
|
||||
this.symbol = symbol;
|
||||
private final String path;
|
||||
private final String[] httpMethods;
|
||||
private final String[] contentTypes;
|
||||
private final String[] acceptTypes;
|
||||
|
||||
public WebfluxHandlerInformation(String handlerClass, String handlerMethod, String path, String[] httpMethods, String[] contentTypes, String[] acceptTypes) {
|
||||
this.handlerClass = handlerClass;
|
||||
this.handlerMethod = handlerMethod;
|
||||
}
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
|
||||
this.path = path;
|
||||
this.httpMethods = httpMethods;
|
||||
this.contentTypes = contentTypes;
|
||||
this.acceptTypes = acceptTypes;
|
||||
}
|
||||
|
||||
public String getHandlerClass() {
|
||||
@@ -36,5 +40,21 @@ public class WebfluxHandlerInformation {
|
||||
public String getHandlerMethod() {
|
||||
return handlerMethod;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public String[] getHttpMethods() {
|
||||
return httpMethods;
|
||||
}
|
||||
|
||||
public String[] getContentTypes() {
|
||||
return contentTypes;
|
||||
}
|
||||
|
||||
public String[] getAcceptTypes() {
|
||||
return acceptTypes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,28 +10,29 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.jdt.core.dom.ASTVisitor;
|
||||
import org.eclipse.jdt.core.dom.IMethodBinding;
|
||||
import org.eclipse.jdt.core.dom.MethodInvocation;
|
||||
import org.eclipse.jdt.core.dom.QualifiedName;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class WebfluxMethodFinder extends ASTVisitor {
|
||||
|
||||
private String method;
|
||||
private Set<String> methods;
|
||||
private ASTNode root;
|
||||
|
||||
public WebfluxMethodFinder(ASTNode root) {
|
||||
this.root = root;
|
||||
this.methods = new LinkedHashSet<>();
|
||||
}
|
||||
|
||||
public String getMethod() {
|
||||
return method;
|
||||
public Set<String> getMethods() {
|
||||
return methods;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -44,10 +45,10 @@ public class WebfluxMethodFinder extends ASTVisitor {
|
||||
if (WebfluxUtils.REQUEST_PREDICATES_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
|
||||
String name = methodBinding.getName();
|
||||
if (name != null && WebfluxUtils.REQUEST_PREDICATE_HTTPMETHOD_METHODS.contains(name)) {
|
||||
method = name;
|
||||
methods.add(name);
|
||||
}
|
||||
else if (name != null && WebfluxUtils.REQUEST_PREDICATE_METHOD_METHOD.equals(name)) {
|
||||
method = extractMethodValue(node);
|
||||
methods.add(WebfluxUtils.extractQualifiedNameArgument(node));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,18 +59,4 @@ public class WebfluxMethodFinder extends ASTVisitor {
|
||||
return visitChildren;
|
||||
}
|
||||
|
||||
private String extractMethodValue(MethodInvocation node) {
|
||||
List<?> arguments = node.arguments();
|
||||
if (arguments != null && arguments.size() > 0) {
|
||||
Object object = arguments.get(0);
|
||||
if (object instanceof QualifiedName) {
|
||||
QualifiedName qualifiedName = (QualifiedName) object;
|
||||
if (qualifiedName.getName() != null) {
|
||||
return qualifiedName.getName().toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public class WebfluxPathFinder extends ASTVisitor {
|
||||
if (WebfluxUtils.REQUEST_PREDICATES_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
|
||||
String name = methodBinding.getName();
|
||||
if (name != null && WebfluxUtils.REQUEST_PREDICATE_ALL_PATH_METHODS.contains(name)) {
|
||||
path = WebfluxUtils.extractPath(node);
|
||||
path = WebfluxUtils.extractStringLiteralArgument(node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.jdt.core.dom.ASTVisitor;
|
||||
@@ -26,8 +28,6 @@ import org.eclipse.jdt.core.dom.MethodInvocation;
|
||||
import org.eclipse.jdt.core.dom.Type;
|
||||
import org.eclipse.jdt.core.dom.TypeDeclaration;
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
import org.eclipse.lsp4j.SymbolKind;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
@@ -87,40 +87,134 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
|
||||
}
|
||||
|
||||
protected void extractMappingSymbol(MethodInvocation node, TextDocument doc, List<EnhancedSymbolInformation> result) {
|
||||
String foundPath = extractPathFromRouterFunction(node);
|
||||
String path = extractPath(node, foundPath);
|
||||
String httpMethod = extractMethod(node);
|
||||
String path = extractPath(node);
|
||||
|
||||
String[] httpMethods = extractMethods(node);
|
||||
String[] contentTypes = extractContentTypes(node);
|
||||
String[] acceptTypes = extractAcceptTypes(node);
|
||||
|
||||
int methodNameStart = node.getName().getStartPosition();
|
||||
int invocationStart = node.getStartPosition();
|
||||
|
||||
if (path != null && path.length() > 0) {
|
||||
try {
|
||||
Location location = new Location(doc.getUri(), doc.toRange(methodNameStart, node.getLength() - (methodNameStart - invocationStart)));
|
||||
String label = "@" + (path.startsWith("/") ? path : ("/" + path)) + (httpMethod == null || httpMethod.isEmpty() ? "" : " -- " + httpMethod);
|
||||
|
||||
WebfluxHandlerInformation handler = extractHandlerInformation(node, label);
|
||||
|
||||
result.add(new EnhancedSymbolInformation(new SymbolInformation(label, SymbolKind.Interface, location), handler));
|
||||
Location location = new Location(doc.getUri(), doc.toRange(methodNameStart, node.getLength() - (methodNameStart - invocationStart)));
|
||||
WebfluxHandlerInformation handler = extractHandlerInformation(node, path, httpMethods, contentTypes, acceptTypes);
|
||||
|
||||
result.add(RouteUtils.createRouteSymbol(location, path, httpMethods, contentTypes, acceptTypes, handler));
|
||||
|
||||
} catch (BadLocationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String extractPathFromRouterFunction(MethodInvocation routerInvocation) {
|
||||
private String extractPath(MethodInvocation routerInvocation) {
|
||||
WebfluxPathFinder pathFinder = new WebfluxPathFinder(routerInvocation);
|
||||
routerInvocation.accept(pathFinder);
|
||||
|
||||
String path = pathFinder.getPath();
|
||||
if (path == null) path = "";
|
||||
List<String> path = new ArrayList<>();
|
||||
String firstPath = pathFinder.getPath();
|
||||
if (firstPath != null) {
|
||||
path.add(firstPath);
|
||||
}
|
||||
|
||||
extractNestedValue(routerInvocation, path, (methodInvocation) -> {
|
||||
IMethodBinding methodBinding = methodInvocation.resolveMethodBinding();
|
||||
String methodName = methodBinding.getName();
|
||||
|
||||
if (WebfluxUtils.REQUEST_PREDICATE_PATH_METHOD.equals(methodName)) {
|
||||
String additionalPath = WebfluxUtils.extractStringLiteralArgument(methodInvocation);
|
||||
if (additionalPath != null && additionalPath.length() > 0) {
|
||||
return additionalPath;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
StringBuilder result = new StringBuilder();
|
||||
path.stream().forEach(part -> result.insert(0, part));
|
||||
|
||||
return result.toString();
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
private String extractPath(ASTNode node, String path) {
|
||||
private String[] extractMethods(MethodInvocation routerInvocation) {
|
||||
WebfluxMethodFinder methodFinder = new WebfluxMethodFinder(routerInvocation);
|
||||
List<?> arguments = routerInvocation.arguments();
|
||||
for (Object argument : arguments) {
|
||||
if (argument != null && argument instanceof ASTNode) {
|
||||
((ASTNode)argument).accept(methodFinder);
|
||||
}
|
||||
}
|
||||
|
||||
final Set<String> methods = methodFinder.getMethods();
|
||||
|
||||
extractNestedValue(routerInvocation, methods, (methodInvocation) -> {
|
||||
IMethodBinding methodBinding = methodInvocation.resolveMethodBinding();
|
||||
String methodName = methodBinding.getName();
|
||||
|
||||
if (WebfluxUtils.REQUEST_PREDICATE_METHOD_METHOD.equals(methodName)) {
|
||||
return WebfluxUtils.extractQualifiedNameArgument(methodInvocation);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
return (String[]) methods.toArray(new String[methods.size()]);
|
||||
}
|
||||
|
||||
private String[] extractAcceptTypes(MethodInvocation routerInvocation) {
|
||||
WebfluxAcceptTypeFinder typeFinder = new WebfluxAcceptTypeFinder();
|
||||
List<?> arguments = routerInvocation.arguments();
|
||||
for (Object argument : arguments) {
|
||||
if (argument != null && argument instanceof ASTNode) {
|
||||
((ASTNode)argument).accept(typeFinder);
|
||||
}
|
||||
}
|
||||
|
||||
Set<String> acceptTypes = typeFinder.getAcceptTypes();
|
||||
|
||||
extractNestedValue(routerInvocation, acceptTypes, (methodInvocation) -> {
|
||||
IMethodBinding methodBinding = methodInvocation.resolveMethodBinding();
|
||||
String methodName = methodBinding.getName();
|
||||
|
||||
if (WebfluxUtils.REQUEST_PREDICATE_ACCEPT_TYPE_METHOD.equals(methodName)) {
|
||||
return WebfluxUtils.extractSimpleNameArgument(methodInvocation);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
return (String[]) acceptTypes.toArray(new String[acceptTypes.size()]);
|
||||
}
|
||||
|
||||
private String[] extractContentTypes(MethodInvocation routerInvocation) {
|
||||
WebfluxContentTypeFinder contentTypeFinder = new WebfluxContentTypeFinder(routerInvocation);
|
||||
List<?> arguments = routerInvocation.arguments();
|
||||
for (Object argument : arguments) {
|
||||
if (argument != null && argument instanceof ASTNode) {
|
||||
((ASTNode)argument).accept(contentTypeFinder);
|
||||
}
|
||||
}
|
||||
|
||||
Set<String> contentTypes = contentTypeFinder.getContentTypes();
|
||||
|
||||
extractNestedValue(routerInvocation, contentTypes, (methodInvocation) -> {
|
||||
IMethodBinding methodBinding = methodInvocation.resolveMethodBinding();
|
||||
String methodName = methodBinding.getName();
|
||||
|
||||
if (WebfluxUtils.REQUEST_PREDICATE_CONTENT_TYPE_METHOD.equals(methodName)) {
|
||||
return WebfluxUtils.extractSimpleNameArgument(methodInvocation);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
return (String[]) contentTypes.toArray(new String[contentTypes.size()]);
|
||||
}
|
||||
|
||||
private void extractNestedValue(ASTNode node, Collection<String> values, Function<MethodInvocation, String> extractor) {
|
||||
if (node == null || node instanceof TypeDeclaration) {
|
||||
return path;
|
||||
return;
|
||||
}
|
||||
|
||||
if (node instanceof MethodInvocation) {
|
||||
@@ -129,39 +223,25 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
|
||||
|
||||
if (WebfluxUtils.ROUTER_FUNCTIONS_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
|
||||
String name = methodBinding.getName();
|
||||
if ("nest".equals(name)) {
|
||||
if (WebfluxUtils.REQUEST_PREDICATE_NEST_METHOD.equals(name)) {
|
||||
List<?> arguments = methodInvocation.arguments();
|
||||
for (Object argument : arguments) {
|
||||
if (argument instanceof MethodInvocation) {
|
||||
MethodInvocation nestedMethod = (MethodInvocation) argument;
|
||||
IMethodBinding nestedMethodBinding = nestedMethod.resolveMethodBinding();
|
||||
|
||||
String nestedMethodName = nestedMethodBinding.getName();
|
||||
if ("path".equals(nestedMethodName)) {
|
||||
String additionalPath = WebfluxUtils.extractPath(nestedMethod);
|
||||
if (additionalPath != null && additionalPath.length() > 0) {
|
||||
path = additionalPath + path;
|
||||
}
|
||||
String value = extractor.apply(nestedMethod);
|
||||
if (value != null) {
|
||||
values.add(value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return extractPath(node.getParent(), path);
|
||||
extractNestedValue(node.getParent(), values, extractor);
|
||||
}
|
||||
|
||||
private String extractMethod(MethodInvocation routerInvocation) {
|
||||
WebfluxMethodFinder methodFinder = new WebfluxMethodFinder(routerInvocation);
|
||||
routerInvocation.accept(methodFinder);
|
||||
|
||||
String method = methodFinder.getMethod();
|
||||
return method;
|
||||
}
|
||||
|
||||
private WebfluxHandlerInformation extractHandlerInformation(MethodInvocation node, String symbol) {
|
||||
private WebfluxHandlerInformation extractHandlerInformation(MethodInvocation node, String path, String[] httpMethods, String[] contentTypes, String[] acceptTypes) {
|
||||
List<?> arguments = node.arguments();
|
||||
|
||||
if (arguments != null) {
|
||||
@@ -177,7 +257,7 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
|
||||
String handlerMethod = methodBinding.getMethodDeclaration().toString();
|
||||
if (handlerMethod != null) handlerMethod = handlerMethod.trim();
|
||||
|
||||
return new WebfluxHandlerInformation(symbol, handlerClass, handlerMethod);
|
||||
return new WebfluxHandlerInformation(handlerClass, handlerMethod, path, httpMethods, contentTypes, acceptTypes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,9 +14,12 @@ import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.eclipse.jdt.core.dom.IMethodBinding;
|
||||
import org.eclipse.jdt.core.dom.MethodInvocation;
|
||||
import org.eclipse.jdt.core.dom.QualifiedName;
|
||||
import org.eclipse.jdt.core.dom.SimpleName;
|
||||
import org.eclipse.jdt.core.dom.StringLiteral;
|
||||
|
||||
/**
|
||||
@@ -30,12 +33,15 @@ public class WebfluxUtils {
|
||||
|
||||
public static final String REQUEST_PREDICATE_PATH_METHOD = "path";
|
||||
public static final String REQUEST_PREDICATE_METHOD_METHOD = "method";
|
||||
public static final String REQUEST_PREDICATE_ACCEPT_TYPE_METHOD = "accept";
|
||||
public static final String REQUEST_PREDICATE_CONTENT_TYPE_METHOD = "contentType";
|
||||
public static final String REQUEST_PREDICATE_NEST_METHOD = "nest";
|
||||
|
||||
public static final Set<String> REQUEST_PREDICATE_HTTPMETHOD_METHODS = new HashSet<>(Arrays.asList("GET", "POST", "DELETE", "PUT", "PATCH", "HEAD", "OPTIONS"));
|
||||
public static final Set<String> REQUEST_PREDICATE_ALL_PATH_METHODS = new HashSet<>(Arrays.asList(REQUEST_PREDICATE_PATH_METHOD, "GET", "POST", "DELETE", "PUT", "PATCH", "HEAD", "OPTIONS"));
|
||||
|
||||
|
||||
public static String extractPath(MethodInvocation node) {
|
||||
public static String extractStringLiteralArgument(MethodInvocation node) {
|
||||
List<?> arguments = node.arguments();
|
||||
if (arguments != null && arguments.size() > 0) {
|
||||
Object object = arguments.get(0);
|
||||
@@ -47,6 +53,34 @@ public class WebfluxUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String extractQualifiedNameArgument(MethodInvocation node) {
|
||||
List<?> arguments = node.arguments();
|
||||
if (arguments != null && arguments.size() > 0) {
|
||||
Object object = arguments.get(0);
|
||||
if (object instanceof QualifiedName) {
|
||||
QualifiedName qualifiedName = (QualifiedName) object;
|
||||
if (qualifiedName.getName() != null) {
|
||||
return qualifiedName.getName().toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String extractSimpleNameArgument(MethodInvocation node) {
|
||||
List<?> arguments = node.arguments();
|
||||
if (arguments != null && arguments.size() > 0) {
|
||||
Object object = arguments.get(0);
|
||||
if (object instanceof SimpleName) {
|
||||
SimpleName name = (SimpleName) object;
|
||||
if (name.getFullyQualifiedName() != null) {
|
||||
return name.getFullyQualifiedName().toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isRouteMethodInvocation(IMethodBinding methodBinding) {
|
||||
if (ROUTER_FUNCTIONS_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
|
||||
String name = methodBinding.getName();
|
||||
@@ -62,8 +96,39 @@ public class WebfluxUtils {
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public static String getMediaType(String constantRep) {
|
||||
if (constantRep == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
if (constantRep.endsWith("_VALUE")) {
|
||||
constantRep = constantRep.substring(0, constantRep.lastIndexOf("_VALUE"));
|
||||
}
|
||||
|
||||
MediaTypeMapping mediaType = MediaTypeMapping.valueOf(constantRep);
|
||||
return mediaType.getMediaType();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
return constantRep;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getStringRep(String[] multipleTypes, Function<String, String> valueConverter) {
|
||||
if (multipleTypes == null || multipleTypes.length == 0) return null;
|
||||
|
||||
StringBuilder result = new StringBuilder(valueConverter.apply(multipleTypes[0]));
|
||||
for (int i = 1; i < multipleTypes.length; i++) {
|
||||
result.append(",");
|
||||
result.append(valueConverter.apply(multipleTypes[i]));
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ public class RequestMappingSymbolProviderTest {
|
||||
@Test
|
||||
public void testSimpleRequestMappingSymbol() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()));
|
||||
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI());
|
||||
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/SimpleMappingClass.java").toUri().toString();
|
||||
@@ -50,7 +49,6 @@ public class RequestMappingSymbolProviderTest {
|
||||
@Test
|
||||
public void testParentRequestMappingSymbol() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()));
|
||||
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI());
|
||||
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/ParentMappingClass.java").toUri().toString();
|
||||
@@ -62,7 +60,6 @@ public class RequestMappingSymbolProviderTest {
|
||||
@Test
|
||||
public void testEmptyPathWithParentRequestMappingSymbol() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()));
|
||||
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI());
|
||||
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/ParentMappingClass2.java").toUri().toString();
|
||||
@@ -74,7 +71,6 @@ public class RequestMappingSymbolProviderTest {
|
||||
@Test
|
||||
public void testMultiRequestMappingSymbol() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()));
|
||||
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI());
|
||||
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/MultiRequestMappingClass.java").toUri().toString();
|
||||
@@ -87,7 +83,6 @@ public class RequestMappingSymbolProviderTest {
|
||||
@Test
|
||||
public void testGetMappingSymbol() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()));
|
||||
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI());
|
||||
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/RequestMethodClass.java").toUri().toString();
|
||||
@@ -98,7 +93,6 @@ public class RequestMappingSymbolProviderTest {
|
||||
@Test
|
||||
public void testDeleteMappingSymbol() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()));
|
||||
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI());
|
||||
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/RequestMethodClass.java").toUri().toString();
|
||||
@@ -109,7 +103,6 @@ public class RequestMappingSymbolProviderTest {
|
||||
@Test
|
||||
public void testPostMappingSymbol() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()));
|
||||
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI());
|
||||
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/RequestMethodClass.java").toUri().toString();
|
||||
@@ -120,7 +113,6 @@ public class RequestMappingSymbolProviderTest {
|
||||
@Test
|
||||
public void testPutMappingSymbol() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()));
|
||||
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI());
|
||||
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/RequestMethodClass.java").toUri().toString();
|
||||
@@ -131,7 +123,6 @@ public class RequestMappingSymbolProviderTest {
|
||||
@Test
|
||||
public void testPatchMappingSymbol() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()));
|
||||
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI());
|
||||
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/RequestMethodClass.java").toUri().toString();
|
||||
@@ -142,7 +133,6 @@ public class RequestMappingSymbolProviderTest {
|
||||
@Test
|
||||
public void testGetRequestMappingSymbol() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()));
|
||||
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI());
|
||||
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/RequestMethodClass.java").toUri().toString();
|
||||
@@ -153,13 +143,31 @@ public class RequestMappingSymbolProviderTest {
|
||||
@Test
|
||||
public void testMultiRequestMethodMappingSymbol() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()));
|
||||
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI());
|
||||
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/RequestMethodClass.java").toUri().toString();
|
||||
List<? extends SymbolInformation> symbols = getSymbols(docUri);
|
||||
assertTrue(containsSymbol(symbols, "@/postAndPutHello -- POST,PUT", docUri, 36, 1, 36, 76));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMediaTypes() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI()));
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-request-mapping-symbols/").toURI());
|
||||
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/RequestMappingMediaTypes.java").toUri().toString();
|
||||
List<? extends SymbolInformation> symbols = getSymbols(docUri);
|
||||
assertEquals(7, symbols.size());
|
||||
assertTrue(containsSymbol(symbols, "@/consume1 -- HEAD - Accept: testconsume", docUri, 8, 1, 8, 90));
|
||||
assertTrue(containsSymbol(symbols, "@/consume2 - Accept: text/plain", docUri, 13, 1, 13, 73));
|
||||
assertTrue(containsSymbol(symbols, "@/consume3 - Accept: text/plain,testconsumetype", docUri, 18, 1, 18, 94));
|
||||
assertTrue(containsSymbol(symbols, "@/produce1 - Content-Type: testproduce", docUri, 23, 1, 23, 60));
|
||||
assertTrue(containsSymbol(symbols, "@/produce2 - Content-Type: text/plain", docUri, 28, 1, 28, 73));
|
||||
assertTrue(containsSymbol(symbols, "@/produce3 - Content-Type: text/plain,testproducetype", docUri, 33, 1, 33, 94));
|
||||
assertTrue(containsSymbol(symbols, "@/everything - Accept: application/json,text/plain,testconsume - Content-Type: application/json", docUri, 38, 1, 38, 170));
|
||||
}
|
||||
|
||||
|
||||
|
||||
private boolean containsSymbol(List<? extends SymbolInformation> symbols, String name, String uri, int startLine, int startCHaracter, int endLine, int endCharacter) {
|
||||
for (Iterator<? extends SymbolInformation> iterator = symbols.iterator(); iterator.hasNext();) {
|
||||
|
||||
@@ -41,7 +41,7 @@ public class WebFluxCodeLensProviderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRoutesCodeLenses() throws Exception {
|
||||
public void testRoutesCodeLensesSimpleCase() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI()));
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI());
|
||||
|
||||
@@ -53,10 +53,65 @@ public class WebFluxCodeLensProviderTest {
|
||||
|
||||
assertEquals(4, codeLenses.size());
|
||||
|
||||
assertTrue(containsCodeLens(codeLenses, "@/hello -- GET", 25, 29, 25, 34));
|
||||
assertTrue(containsCodeLens(codeLenses, "@/echo -- POST", 30, 29, 30, 33));
|
||||
assertTrue(containsCodeLens(codeLenses, "@/quotes -- GET", 35, 29, 35, 41));
|
||||
assertTrue(containsCodeLens(codeLenses, "@/quotes -- GET", 41, 29, 41, 40));
|
||||
assertTrue(containsCodeLens(codeLenses, "GET /hello - Accept: text/plain", 25, 29, 25, 34));
|
||||
assertTrue(containsCodeLens(codeLenses, "POST /echo - Accept: text/plain - Content-Type: text/plain", 30, 29, 30, 33));
|
||||
assertTrue(containsCodeLens(codeLenses, "GET /quotes - Accept: application/stream+json", 35, 29, 35, 41));
|
||||
assertTrue(containsCodeLens(codeLenses, "GET /quotes - Accept: application/json", 41, 29, 41, 40));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRoutesCodeLensesNestedRoutes1() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI()));
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI());
|
||||
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/PersonHandler1.java").toUri().toString();
|
||||
TextDocumentInfo doc = harness.getOrReadFile(new File(new URI(docUri)), LanguageId.JAVA.toString());
|
||||
TextDocumentInfo openedDoc = harness.openDocument(doc);
|
||||
|
||||
List<? extends CodeLens> codeLenses = harness.getCodeLenses(openedDoc);
|
||||
|
||||
assertEquals(3, codeLenses.size());
|
||||
|
||||
assertTrue(containsCodeLens(codeLenses, "GET /person/{id} - Accept: application/json", 9, 29, 9, 38));
|
||||
assertTrue(containsCodeLens(codeLenses, "POST /person/ - Content-Type: application/json", 13, 29, 13, 41));
|
||||
assertTrue(containsCodeLens(codeLenses, "GET /person - Accept: application/json", 17, 29, 17, 39));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRoutesCodeLensesNestedRoutes2() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI()));
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI());
|
||||
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/PersonHandler2.java").toUri().toString();
|
||||
TextDocumentInfo doc = harness.getOrReadFile(new File(new URI(docUri)), LanguageId.JAVA.toString());
|
||||
TextDocumentInfo openedDoc = harness.openDocument(doc);
|
||||
|
||||
List<? extends CodeLens> codeLenses = harness.getCodeLenses(openedDoc);
|
||||
|
||||
assertEquals(3, codeLenses.size());
|
||||
|
||||
assertTrue(containsCodeLens(codeLenses, "GET /person/{id} - Accept: application/json", 9, 29, 9, 38));
|
||||
assertTrue(containsCodeLens(codeLenses, "POST / - Accept: application/json - Content-Type: application/json,application/pdf", 13, 29, 13, 41));
|
||||
assertTrue(containsCodeLens(codeLenses, "GET,HEAD /person - Accept: text/plain,application/json", 17, 29, 17, 39));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRoutesCodeLensesNestedRoutes3() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI()));
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI());
|
||||
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/PersonHandler3.java").toUri().toString();
|
||||
TextDocumentInfo doc = harness.getOrReadFile(new File(new URI(docUri)), LanguageId.JAVA.toString());
|
||||
TextDocumentInfo openedDoc = harness.openDocument(doc);
|
||||
|
||||
List<? extends CodeLens> codeLenses = harness.getCodeLenses(openedDoc);
|
||||
|
||||
assertEquals(6, codeLenses.size());
|
||||
/*
|
||||
assertTrue(containsCodeLens(codeLenses, "GET /person/{id} - Accept: application/json", 9, 29, 9, 38));
|
||||
assertTrue(containsCodeLens(codeLenses, "POST / - Accept: application/json - Content-Type: application/json, application/pdf", 13, 29, 13, 41));
|
||||
assertTrue(containsCodeLens(codeLenses, "GET, HEAD /person - Accept: text/plain, application/json", 17, 29, 17, 39));
|
||||
*/
|
||||
}
|
||||
|
||||
private boolean containsCodeLens(List<? extends CodeLens> codeLenses, String commandTitle, int startLine, int startPosition, int endLine, int endPosition) {
|
||||
|
||||
@@ -15,6 +15,7 @@ import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -46,8 +47,8 @@ public class WebFluxMappingSymbolProviderTest {
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/UserController.java").toUri().toString();
|
||||
List<? extends SymbolInformation> symbols = getSymbols(docUri);
|
||||
assertEquals(4, symbols.size());
|
||||
assertTrue(containsSymbol(symbols, "@/users", docUri, 19, 1, 19, 74));
|
||||
assertTrue(containsSymbol(symbols, "@/users/{username}", docUri, 24, 1, 24, 85));
|
||||
assertTrue(containsSymbol(symbols, "@/users - Content-Type: application/json", docUri, 13, 1, 13, 74));
|
||||
assertTrue(containsSymbol(symbols, "@/users/{username} - Content-Type: application/json", docUri, 18, 1, 18, 85));
|
||||
|
||||
List<? extends Object> addons = getAdditionalInformation(docUri);
|
||||
assertNull(addons);
|
||||
@@ -61,66 +62,195 @@ public class WebFluxMappingSymbolProviderTest {
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/QuoteRouter.java").toUri().toString();
|
||||
List<? extends SymbolInformation> symbols = getSymbols(docUri);
|
||||
assertEquals(6, symbols.size());
|
||||
assertTrue(containsSymbol(symbols, "@/hello -- GET", docUri, 22, 5, 22, 70));
|
||||
assertTrue(containsSymbol(symbols, "@/echo -- POST", docUri, 23, 5, 23, 101));
|
||||
assertTrue(containsSymbol(symbols, "@/quotes -- GET", docUri, 24, 5, 24, 86));
|
||||
assertTrue(containsSymbol(symbols, "@/quotes -- GET", docUri, 25, 5, 25, 94));
|
||||
assertTrue(containsSymbol(symbols, "@/hello -- GET - Accept: text/plain", docUri, 22, 5, 22, 70));
|
||||
assertTrue(containsSymbol(symbols, "@/echo -- POST - Accept: text/plain - Content-Type: text/plain", docUri, 23, 5, 23, 101));
|
||||
assertTrue(containsSymbol(symbols, "@/quotes -- GET - Accept: application/json", docUri, 24, 5, 24, 86));
|
||||
assertTrue(containsSymbol(symbols, "@/quotes -- GET - Accept: application/stream+json", docUri, 25, 5, 25, 94));
|
||||
|
||||
List<? extends Object> addons = getAdditionalInformation(docUri);
|
||||
assertEquals(4, addons.size());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo1 = getWebfluxHandler(addons, "@/hello -- GET").get(0);
|
||||
assertEquals("@/hello -- GET", handlerInfo1.getSymbol());
|
||||
WebfluxHandlerInformation handlerInfo1 = getWebfluxHandler(addons, "/hello", "GET").get(0);
|
||||
assertEquals("/hello", handlerInfo1.getPath());
|
||||
assertEquals("[GET]", Arrays.toString(handlerInfo1.getHttpMethods()));
|
||||
assertEquals(0, handlerInfo1.getContentTypes().length);
|
||||
assertEquals("[TEXT_PLAIN]", Arrays.toString(handlerInfo1.getAcceptTypes()));
|
||||
assertEquals("org.test.QuoteHandler", handlerInfo1.getHandlerClass());
|
||||
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> hello(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo1.getHandlerMethod());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo2 = getWebfluxHandler(addons, "@/echo -- POST").get(0);
|
||||
assertEquals("@/echo -- POST", handlerInfo2.getSymbol());
|
||||
WebfluxHandlerInformation handlerInfo2 = getWebfluxHandler(addons, "/echo", "POST").get(0);
|
||||
assertEquals("/echo", handlerInfo2.getPath());
|
||||
assertEquals("[POST]", Arrays.toString(handlerInfo2.getHttpMethods()));
|
||||
assertEquals("[TEXT_PLAIN]", Arrays.toString(handlerInfo2.getContentTypes()));
|
||||
assertEquals("[TEXT_PLAIN]", Arrays.toString(handlerInfo2.getAcceptTypes()));
|
||||
assertEquals("org.test.QuoteHandler", handlerInfo2.getHandlerClass());
|
||||
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> echo(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo2.getHandlerMethod());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo3 = getWebfluxHandler(addons, "@/quotes -- GET").get(0);
|
||||
assertEquals("@/quotes -- GET", handlerInfo3.getSymbol());
|
||||
WebfluxHandlerInformation handlerInfo3 = getWebfluxHandler(addons, "/quotes", "GET").get(0);
|
||||
assertEquals("/quotes", handlerInfo3.getPath());
|
||||
assertEquals("[GET]", Arrays.toString(handlerInfo3.getHttpMethods()));
|
||||
assertEquals(0, handlerInfo3.getContentTypes().length);
|
||||
assertEquals("[APPLICATION_STREAM_JSON]", Arrays.toString(handlerInfo3.getAcceptTypes()));
|
||||
assertEquals("org.test.QuoteHandler", handlerInfo3.getHandlerClass());
|
||||
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> streamQuotes(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo3.getHandlerMethod());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo4 = getWebfluxHandler(addons, "@/quotes -- GET").get(1);
|
||||
assertEquals("@/quotes -- GET", handlerInfo4.getSymbol());
|
||||
WebfluxHandlerInformation handlerInfo4 = getWebfluxHandler(addons, "/quotes", "GET").get(1);
|
||||
assertEquals("/quotes", handlerInfo4.getPath());
|
||||
assertEquals("[GET]", Arrays.toString(handlerInfo4.getHttpMethods()));
|
||||
assertEquals(0, handlerInfo4.getContentTypes().length);
|
||||
assertEquals("[APPLICATION_JSON]", Arrays.toString(handlerInfo4.getAcceptTypes()));
|
||||
assertEquals("org.test.QuoteHandler", handlerInfo4.getHandlerClass());
|
||||
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> fetchQuotes(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo4.getHandlerMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNestedRoutesMappingSymbols() throws Exception {
|
||||
public void testNestedRoutesMappingSymbols1() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI()));
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI());
|
||||
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/NestedRouter.java").toUri().toString();
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/NestedRouter1.java").toUri().toString();
|
||||
List<? extends SymbolInformation> symbols = getSymbols(docUri);
|
||||
assertEquals(5, symbols.size());
|
||||
assertTrue(containsSymbol(symbols, "@/person/{id} -- GET", docUri, 27, 6, 27, 45));
|
||||
assertTrue(containsSymbol(symbols, "@/person/ -- POST", docUri, 29, 6, 29, 83));
|
||||
assertTrue(containsSymbol(symbols, "@/person -- GET", docUri, 28, 7, 28, 60));
|
||||
assertTrue(containsSymbol(symbols, "@/person/{id} -- GET - Accept: application/json", docUri, 27, 6, 27, 45));
|
||||
assertTrue(containsSymbol(symbols, "@/person/ -- POST - Content-Type: application/json", docUri, 29, 6, 29, 83));
|
||||
assertTrue(containsSymbol(symbols, "@/person -- GET - Accept: application/json", docUri, 28, 7, 28, 60));
|
||||
|
||||
List<? extends Object> addons = getAdditionalInformation(docUri);
|
||||
assertEquals(3, addons.size());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo1 = getWebfluxHandler(addons, "@/person/{id} -- GET").get(0);
|
||||
assertEquals("@/person/{id} -- GET", handlerInfo1.getSymbol());
|
||||
assertEquals("org.test.PersonHandler", handlerInfo1.getHandlerClass());
|
||||
WebfluxHandlerInformation handlerInfo1 = getWebfluxHandler(addons, "/person/{id}", "GET").get(0);
|
||||
assertEquals("/person/{id}", handlerInfo1.getPath());
|
||||
assertEquals("[GET]", Arrays.toString(handlerInfo1.getHttpMethods()));
|
||||
assertEquals(0, handlerInfo1.getContentTypes().length);
|
||||
assertEquals("[APPLICATION_JSON]", Arrays.toString(handlerInfo1.getAcceptTypes()));
|
||||
assertEquals("org.test.PersonHandler1", handlerInfo1.getHandlerClass());
|
||||
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> getPerson(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo1.getHandlerMethod());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo2 = getWebfluxHandler(addons, "@/person/ -- POST").get(0);
|
||||
assertEquals("@/person/ -- POST", handlerInfo2.getSymbol());
|
||||
assertEquals("org.test.PersonHandler", handlerInfo2.getHandlerClass());
|
||||
WebfluxHandlerInformation handlerInfo2 = getWebfluxHandler(addons, "/person/", "POST").get(0);
|
||||
assertEquals("/person/", handlerInfo2.getPath());
|
||||
assertEquals("[POST]", Arrays.toString(handlerInfo2.getHttpMethods()));
|
||||
assertEquals("[APPLICATION_JSON]", Arrays.toString(handlerInfo2.getContentTypes()));
|
||||
assertEquals(0, handlerInfo2.getAcceptTypes().length);
|
||||
assertEquals("org.test.PersonHandler1", handlerInfo2.getHandlerClass());
|
||||
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> createPerson(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo2.getHandlerMethod());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo3 = getWebfluxHandler(addons, "@/person -- GET").get(0);
|
||||
assertEquals("@/person -- GET", handlerInfo3.getSymbol());
|
||||
assertEquals("org.test.PersonHandler", handlerInfo3.getHandlerClass());
|
||||
WebfluxHandlerInformation handlerInfo3 = getWebfluxHandler(addons, "/person", "GET").get(0);
|
||||
assertEquals("/person", handlerInfo3.getPath());
|
||||
assertEquals("[GET]", Arrays.toString(handlerInfo3.getHttpMethods()));
|
||||
assertEquals(0, handlerInfo3.getContentTypes().length);
|
||||
assertEquals("[APPLICATION_JSON]", Arrays.toString(handlerInfo3.getAcceptTypes()));
|
||||
assertEquals("org.test.PersonHandler1", handlerInfo3.getHandlerClass());
|
||||
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> listPeople(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo3.getHandlerMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNestedRoutesMappingSymbols2() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI()));
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI());
|
||||
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/NestedRouter2.java").toUri().toString();
|
||||
List<? extends SymbolInformation> symbols = getSymbols(docUri);
|
||||
assertEquals(5, symbols.size());
|
||||
assertTrue(containsSymbol(symbols, "@/person/{id} -- GET - Accept: application/json", docUri, 29, 6, 29, 45));
|
||||
assertTrue(containsSymbol(symbols, "@/ -- POST - Accept: application/json - Content-Type: application/json,application/pdf", docUri, 31, 6, 31, 117));
|
||||
assertTrue(containsSymbol(symbols, "@/person -- GET,HEAD - Accept: text/plain,application/json", docUri, 30, 7, 30, 113));
|
||||
|
||||
List<? extends Object> addons = getAdditionalInformation(docUri);
|
||||
assertEquals(3, addons.size());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo1 = getWebfluxHandler(addons, "/person/{id}", "GET").get(0);
|
||||
assertEquals("/person/{id}", handlerInfo1.getPath());
|
||||
assertEquals("[GET]", Arrays.toString(handlerInfo1.getHttpMethods()));
|
||||
assertEquals(0, handlerInfo1.getContentTypes().length);
|
||||
assertEquals("[APPLICATION_JSON]", Arrays.toString(handlerInfo1.getAcceptTypes()));
|
||||
assertEquals("org.test.PersonHandler2", handlerInfo1.getHandlerClass());
|
||||
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> getPerson(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo1.getHandlerMethod());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo2 = getWebfluxHandler(addons, "/", "POST").get(0);
|
||||
assertEquals("/", handlerInfo2.getPath());
|
||||
assertEquals("[POST]", Arrays.toString(handlerInfo2.getHttpMethods()));
|
||||
assertEquals("[APPLICATION_JSON, APPLICATION_PDF]", Arrays.toString(handlerInfo2.getContentTypes()));
|
||||
assertEquals("[APPLICATION_JSON]", Arrays.toString(handlerInfo2.getAcceptTypes()));
|
||||
assertEquals("org.test.PersonHandler2", handlerInfo2.getHandlerClass());
|
||||
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> createPerson(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo2.getHandlerMethod());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo3 = getWebfluxHandler(addons, "/person", "HEAD").get(0);
|
||||
assertEquals("/person", handlerInfo3.getPath());
|
||||
assertEquals("[GET, HEAD]", Arrays.toString(handlerInfo3.getHttpMethods()));
|
||||
assertEquals(0, handlerInfo3.getContentTypes().length);
|
||||
assertEquals("[TEXT_PLAIN, APPLICATION_JSON]", Arrays.toString(handlerInfo3.getAcceptTypes()));
|
||||
assertEquals("org.test.PersonHandler2", handlerInfo3.getHandlerClass());
|
||||
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> listPeople(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo3.getHandlerMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNestedRoutesMappingSymbols3() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI()));
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI());
|
||||
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/NestedRouter3.java").toUri().toString();
|
||||
List<? extends SymbolInformation> symbols = getSymbols(docUri);
|
||||
assertEquals(8, symbols.size());
|
||||
|
||||
assertTrue(containsSymbol(symbols, "@/person/sub1/sub2/{id} -- GET - Accept: application/json", docUri, 29, 7, 29, 46));
|
||||
assertTrue(containsSymbol(symbols, "@/person/sub1/sub2 -- GET - Accept: application/json", docUri, 30, 8, 30, 61));
|
||||
assertTrue(containsSymbol(symbols, "@/person/sub1/sub2/nestedGet -- GET", docUri, 31, 9, 31, 56));
|
||||
assertTrue(containsSymbol(symbols, "@/person/sub1/andNestPath/andNestPathGET -- GET", docUri, 33, 5, 33, 54));
|
||||
assertTrue(containsSymbol(symbols, "@/person/ -- POST - Content-Type: application/json", docUri, 34, 5, 34, 82));
|
||||
assertTrue(containsSymbol(symbols, "@/nestedDelete -- DELETE", docUri, 35, 42, 35, 93));
|
||||
|
||||
List<? extends Object> addons = getAdditionalInformation(docUri);
|
||||
assertEquals(6, addons.size());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo1 = getWebfluxHandler(addons, "/person/sub1/sub2/{id}", "GET").get(0);
|
||||
assertEquals("/person/sub1/sub2/{id}", handlerInfo1.getPath());
|
||||
assertEquals("[GET]", Arrays.toString(handlerInfo1.getHttpMethods()));
|
||||
assertEquals(0, handlerInfo1.getContentTypes().length);
|
||||
assertEquals("[APPLICATION_JSON]", Arrays.toString(handlerInfo1.getAcceptTypes()));
|
||||
assertEquals("org.test.PersonHandler3", handlerInfo1.getHandlerClass());
|
||||
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> getPerson(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo1.getHandlerMethod());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo2 = getWebfluxHandler(addons, "/person/sub1/sub2", "GET").get(0);
|
||||
assertEquals("/person/sub1/sub2", handlerInfo2.getPath());
|
||||
assertEquals("[GET]", Arrays.toString(handlerInfo2.getHttpMethods()));
|
||||
assertEquals(0, handlerInfo2.getContentTypes().length);
|
||||
assertEquals("[APPLICATION_JSON]", Arrays.toString(handlerInfo2.getAcceptTypes()));
|
||||
assertEquals("org.test.PersonHandler3", handlerInfo1.getHandlerClass());
|
||||
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> listPeople(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo2.getHandlerMethod());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo3 = getWebfluxHandler(addons, "/person/sub1/sub2/nestedGet", "GET").get(0);
|
||||
assertEquals("/person/sub1/sub2/nestedGet", handlerInfo3.getPath());
|
||||
assertEquals("[GET]", Arrays.toString(handlerInfo3.getHttpMethods()));
|
||||
assertEquals(0, handlerInfo3.getContentTypes().length);
|
||||
assertEquals(0, handlerInfo3.getAcceptTypes().length);
|
||||
assertEquals("org.test.PersonHandler3", handlerInfo1.getHandlerClass());
|
||||
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> getPerson(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo3.getHandlerMethod());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo4 = getWebfluxHandler(addons, "/person/sub1/andNestPath/andNestPathGET", "GET").get(0);
|
||||
assertEquals("/person/sub1/andNestPath/andNestPathGET", handlerInfo4.getPath());
|
||||
assertEquals("[GET]", Arrays.toString(handlerInfo4.getHttpMethods()));
|
||||
assertEquals(0, handlerInfo4.getContentTypes().length);
|
||||
assertEquals(0, handlerInfo4.getAcceptTypes().length);
|
||||
assertEquals("org.test.PersonHandler3", handlerInfo4.getHandlerClass());
|
||||
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> getPerson(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo4.getHandlerMethod());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo5 = getWebfluxHandler(addons, "/person/", "POST").get(0);
|
||||
assertEquals("/person/", handlerInfo5.getPath());
|
||||
assertEquals("[POST]", Arrays.toString(handlerInfo5.getHttpMethods()));
|
||||
assertEquals("[APPLICATION_JSON]", Arrays.toString(handlerInfo5.getContentTypes()));
|
||||
assertEquals(0, handlerInfo5.getAcceptTypes().length);
|
||||
assertEquals("org.test.PersonHandler3", handlerInfo5.getHandlerClass());
|
||||
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> createPerson(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo5.getHandlerMethod());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo6 = getWebfluxHandler(addons, "/nestedDelete", "DELETE").get(0);
|
||||
assertEquals("/nestedDelete", handlerInfo6.getPath());
|
||||
assertEquals("[DELETE]", Arrays.toString(handlerInfo6.getHttpMethods()));
|
||||
assertEquals(0, handlerInfo6.getContentTypes().length);
|
||||
assertEquals(0, handlerInfo6.getAcceptTypes().length);
|
||||
assertEquals("org.test.PersonHandler3", handlerInfo6.getHandlerClass());
|
||||
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> deletePerson(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo6.getHandlerMethod());
|
||||
}
|
||||
|
||||
private boolean containsSymbol(List<? extends SymbolInformation> symbols, String name, String uri, int startLine, int startCHaracter, int endLine, int endCharacter) {
|
||||
for (Iterator<? extends SymbolInformation> iterator = symbols.iterator(); iterator.hasNext();) {
|
||||
SymbolInformation symbol = iterator.next();
|
||||
@@ -146,11 +276,11 @@ public class WebFluxMappingSymbolProviderTest {
|
||||
return harness.getServerWrapper().getComponents().getSpringIndexer().getAdditonalInformation(docUri);
|
||||
}
|
||||
|
||||
private List<WebfluxHandlerInformation> getWebfluxHandler(List<? extends Object> addons, String symbol) {
|
||||
private List<WebfluxHandlerInformation> getWebfluxHandler(List<? extends Object> addons, String path, String httpMethod) {
|
||||
return addons.stream()
|
||||
.filter((obj) -> obj instanceof WebfluxHandlerInformation)
|
||||
.map((obj -> (WebfluxHandlerInformation) obj))
|
||||
.filter((addon) -> addon.getSymbol().equals(symbol))
|
||||
.filter((addon) -> addon.getPath().equals(path) && Arrays.asList(addon.getHttpMethods()).contains(httpMethod))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package org.test;
|
||||
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
public class RequestMappingMediaTypes {
|
||||
|
||||
@RequestMapping(path="/consume1", consumes = "testconsume", method= {RequestMethod.HEAD})
|
||||
public String consume1() {
|
||||
return "Hello";
|
||||
}
|
||||
|
||||
@RequestMapping(path="/consume2", consumes = MediaType.TEXT_PLAIN_VALUE)
|
||||
public String consume2() {
|
||||
return "Hello";
|
||||
}
|
||||
|
||||
@RequestMapping(path="/consume3", consumes = {MediaType.TEXT_PLAIN_VALUE, "testconsumetype"})
|
||||
public String consume3() {
|
||||
return "Hello";
|
||||
}
|
||||
|
||||
@RequestMapping(path="/produce1", produces = "testproduce")
|
||||
public String produce1() {
|
||||
return "Hello";
|
||||
}
|
||||
|
||||
@RequestMapping(path="/produce2", produces = MediaType.TEXT_PLAIN_VALUE)
|
||||
public String produce2() {
|
||||
return "Hello";
|
||||
}
|
||||
|
||||
@RequestMapping(path="/produce3", produces = {MediaType.TEXT_PLAIN_VALUE, "testproducetype"})
|
||||
public String produce3() {
|
||||
return "Hello";
|
||||
}
|
||||
|
||||
@RequestMapping(path="/everything", consumes = { MediaType.APPLICATION_JSON_VALUE, MediaType.TEXT_PLAIN_VALUE, "testconsume"}, produces=MediaType.APPLICATION_JSON_VALUE)
|
||||
public String everything() {
|
||||
return "Hello";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.0.0.M1</version>
|
||||
<version>2.0.0.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
@@ -35,10 +35,6 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@@ -50,42 +46,4 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -17,11 +17,11 @@ import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
|
||||
@Configuration
|
||||
public class NestedRouter {
|
||||
public class NestedRouter1 {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> routingFunction() {
|
||||
PersonHandler handler = new PersonHandler();
|
||||
public RouterFunction<ServerResponse> routingFunction1() {
|
||||
PersonHandler1 handler = new PersonHandler1();
|
||||
|
||||
return nest(path("/person"),
|
||||
nest(accept(APPLICATION_JSON),
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.test;
|
||||
|
||||
import static org.springframework.http.MediaType.APPLICATION_JSON;
|
||||
import static org.springframework.http.MediaType.APPLICATION_PDF;
|
||||
import static org.springframework.http.MediaType.TEXT_PLAIN;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.POST;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.accept;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.contentType;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.method;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.path;
|
||||
import static org.springframework.web.reactive.function.server.RouterFunctions.nest;
|
||||
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
|
||||
@Configuration
|
||||
public class NestedRouter2 {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> routingFunction2() {
|
||||
PersonHandler2 handler = new PersonHandler2();
|
||||
|
||||
return nest(accept(APPLICATION_JSON),
|
||||
nest(path("/person"),
|
||||
route(GET("/{id}"), handler::getPerson)
|
||||
.andRoute(method(HttpMethod.GET).and(method(HttpMethod.HEAD)).and(accept(TEXT_PLAIN)), handler::listPeople)
|
||||
).andRoute(POST("/").and(contentType(APPLICATION_JSON)).and(contentType(APPLICATION_PDF)), handler::createPerson));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package org.test;
|
||||
|
||||
import static org.springframework.http.MediaType.APPLICATION_JSON;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.POST;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.accept;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.contentType;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.method;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.path;
|
||||
import static org.springframework.web.reactive.function.server.RouterFunctions.nest;
|
||||
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
|
||||
@Configuration
|
||||
public class NestedRouter3 {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> routingFunction() {
|
||||
PersonHandler3 handler = new PersonHandler3();
|
||||
|
||||
return nest(path("/person"),
|
||||
nest(path("/sub1"),
|
||||
nest(path("/sub2"),
|
||||
nest(accept(APPLICATION_JSON),
|
||||
route(GET("/{id}"), handler::getPerson)
|
||||
.andRoute(method(HttpMethod.GET), handler::listPeople))
|
||||
.andRoute(GET("/nestedGet"), handler::getPerson))
|
||||
.and(nest(path("/andNestPath"),
|
||||
route(GET("/andNestPathGET"), handler::getPerson))))
|
||||
.andRoute(POST("/").and(contentType(APPLICATION_JSON)), handler::createPerson))
|
||||
.and(nest(method(HttpMethod.DELETE), route(path("/nestedDelete"), handler::deletePerson)));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public class PersonHandler {
|
||||
public class PersonHandler1 {
|
||||
|
||||
public Mono<ServerResponse> getPerson(ServerRequest request) {
|
||||
return ServerResponse.notFound().build();
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.test;
|
||||
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public class PersonHandler2 {
|
||||
|
||||
public Mono<ServerResponse> getPerson(ServerRequest request) {
|
||||
return ServerResponse.notFound().build();
|
||||
}
|
||||
|
||||
public Mono<ServerResponse> createPerson(ServerRequest request) {
|
||||
return ServerResponse.notFound().build();
|
||||
}
|
||||
|
||||
public Mono<ServerResponse> listPeople(ServerRequest request) {
|
||||
return ServerResponse.notFound().build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.test;
|
||||
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public class PersonHandler3 {
|
||||
|
||||
public Mono<ServerResponse> getPerson(ServerRequest request) {
|
||||
return ServerResponse.notFound().build();
|
||||
}
|
||||
|
||||
public Mono<ServerResponse> createPerson(ServerRequest request) {
|
||||
return ServerResponse.notFound().build();
|
||||
}
|
||||
|
||||
public Mono<ServerResponse> listPeople(ServerRequest request) {
|
||||
return ServerResponse.notFound().build();
|
||||
}
|
||||
|
||||
public Mono<ServerResponse> deletePerson(ServerRequest request) {
|
||||
return ServerResponse.notFound().build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
package org.test;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
@Document
|
||||
public class TradingUser {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
private String userName;
|
||||
|
||||
private String fullName;
|
||||
|
||||
public TradingUser() {
|
||||
}
|
||||
|
||||
public TradingUser(String id, String userName, String fullName) {
|
||||
this.id = id;
|
||||
this.userName = userName;
|
||||
this.fullName = fullName;
|
||||
}
|
||||
|
||||
public TradingUser(String userName, String fullName) {
|
||||
this.userName = userName;
|
||||
this.fullName = fullName;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
public void setFullName(String fullName) {
|
||||
this.fullName = fullName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
TradingUser that = (TradingUser) o;
|
||||
|
||||
if (!id.equals(that.id)) return false;
|
||||
return userName.equals(that.userName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = id.hashCode();
|
||||
result = 31 * result + userName.hashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
package org.test;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
|
||||
|
||||
public interface TradingUserRepository extends ReactiveMongoRepository<TradingUser, String> {
|
||||
|
||||
Mono<TradingUser> findByUserName(String userName);
|
||||
|
||||
}
|
||||
@@ -1,30 +1,24 @@
|
||||
package org.test;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@RestController
|
||||
public class UserController {
|
||||
|
||||
private final TradingUserRepository tradingUserRepository;
|
||||
|
||||
public UserController(TradingUserRepository tradingUserRepository) {
|
||||
this.tradingUserRepository = tradingUserRepository;
|
||||
}
|
||||
|
||||
@GetMapping(path = "/users", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public Flux<TradingUser> listUsers() {
|
||||
return this.tradingUserRepository.findAll();
|
||||
public Flux<Object> listUsers() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@GetMapping(path = "/users/{username}", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public Mono<TradingUser> showUsers(@PathVariable String username) {
|
||||
return this.tradingUserRepository.findByUserName(username);
|
||||
public Mono<Object> showUsers(@PathVariable String username) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user