Skip to content

Commit 2a5c291

Browse files
committed
GH-1630: fallback to standard Spring stereotype definitions for projects that do not use jmolecules or Spring Modulith
1 parent 2735128 commit 2a5c291

File tree

10 files changed

+629
-10
lines changed

10 files changed

+629
-10
lines changed

headless-services/spring-boot-language-server/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,12 @@
170170
<version>0.29.0-STEREOTYPE-SNAPSHOT</version>
171171
</dependency>
172172

173+
<dependency>
174+
<groupId>org.jmolecules.integrations</groupId>
175+
<artifactId>jmolecules-spring</artifactId>
176+
<version>0.29.0-STEREOTYPE-SNAPSHOT</version>
177+
</dependency>
178+
173179

174180
<dependency>
175181
<groupId>org.eclipse.lemminx</groupId>

headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/commands/SpringIndexCommands.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,10 @@ public SpringIndexCommands(SimpleLanguageServer server, SpringMetamodelIndex spr
5555
&& params.getArguments().get(0) instanceof JsonPrimitive
5656
? ((JsonPrimitive) params.getArguments().get(0)).getAsBoolean() : false;
5757

58-
return projectFinder.all().stream().map(project -> nodeFrom(stereotypeCatalogRegistry, springIndex, project, updateMetadata)).filter(Objects::nonNull).collect(Collectors.toList());
58+
return projectFinder.all().stream()
59+
.map(project -> nodeFrom(stereotypeCatalogRegistry, springIndex, project, updateMetadata))
60+
.filter(Objects::nonNull)
61+
.collect(Collectors.toList());
5962
}));
6063
}
6164

headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/stereotypes/ProjectBasedCatalogSource.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,17 @@
2121
import java.util.zip.ZipEntry;
2222

2323
import org.jmolecules.stereotype.catalog.support.CatalogSource;
24+
import org.slf4j.Logger;
25+
import org.slf4j.LoggerFactory;
2426
import org.springframework.ide.vscode.commons.java.IClasspath;
2527
import org.springframework.ide.vscode.commons.java.IJavaProject;
2628
import org.springframework.ide.vscode.commons.protocol.java.Classpath;
2729
import org.springframework.ide.vscode.commons.protocol.java.Classpath.CPE;
2830

2931
public class ProjectBasedCatalogSource implements CatalogSource {
3032

33+
private static final Logger log = LoggerFactory.getLogger(ProjectBasedCatalogSource.class);
34+
3135
private final IJavaProject project;
3236

3337
public ProjectBasedCatalogSource(IJavaProject project) {
@@ -75,9 +79,24 @@ public Stream<URL> getSources() {
7579
}
7680
}
7781
}
82+
83+
if (result.size() == 0) {
84+
URL defaultSpringStereotypes = this.getClass().getResource("/stereotype-defaults/jmolecules-stereotypes.json");
85+
86+
if (defaultSpringStereotypes != null) {
87+
log.info("using default stereotypes for project: " + this.project.getElementName());
88+
result.add(defaultSpringStereotypes);
89+
}
90+
else {
91+
log.error("error looking up default stereotypes for project: " + this.project.getElementName());
92+
}
93+
}
94+
7895
} catch (Exception e) {
96+
log.error("error looking up stereotype metadata for project: " + this.project.getElementName(), e);
7997
}
8098

99+
81100
return result.stream();
82101
}
83102

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
{
2+
"stereotypes" : [
3+
{
4+
"id" : "org.springframework.boot.jackson.JsonMixin",
5+
"assignments" : [ "@org.springframework.boot.jackson.JsonMixin" ],
6+
"displayName" : "JSON Mixin",
7+
"groups" : [ "spring.web.rest" ]
8+
},
9+
{
10+
"id" : "org.springframework.context.annotation.Configuration",
11+
"assignments" : [ "@org.springframework.context.annotation.Configuration" ],
12+
"groups" : [ "spring" ]
13+
},
14+
{
15+
"id" : "org.springframework.context.event.EventListener",
16+
"assignments" : [ "@org.springframework.context.event.EventListener" ],
17+
"groups" : [ "spring" ]
18+
},
19+
{
20+
"id" : "org.springframework.data.rest.core.config.Projection",
21+
"assignments" : [ "@org.springframework.data.rest.core.config.Projection" ],
22+
"groups" : [ "spring.data" ]
23+
},
24+
{
25+
"id" : "org.springframework.hateoas.server.RepresentationModelProcessor",
26+
"assignments" : [ "org.springframework.hateoas.server.RepresentationModelProcessor" ],
27+
"groups" : [ "spring.web.rest.hypermedia" ]
28+
},
29+
{
30+
"id" : "org.springframework.stereotype.Controller",
31+
"assignments" : [
32+
"@org.springframework.stereotype.Controller",
33+
"@org.springframework.data.rest.webmvc.BasePathAwareController"
34+
],
35+
"groups" : [ "spring.web" ]
36+
},
37+
{
38+
"id" : "org.springframework.stereotype.Service",
39+
"assignments" : [ "@org.springframework.stereotype.Service" ],
40+
"groups" : [ "spring", "org.jmolecules.ddd" ]
41+
},
42+
{
43+
"id" : "org.springframework.web.bind.annotation.RequestMapping",
44+
"assignments" : [ "@org.springframework.web.bind.annotation.RequestMapping" ],
45+
"displayName" : "Request mappings",
46+
"groups" : [ "spring.web" ]
47+
}
48+
],
49+
"groups" : [
50+
{
51+
"ids" : [ "spring"],
52+
"displayName" : "Spring"
53+
},
54+
{
55+
"ids" : [ "spring.data" ],
56+
"displayName" : "Spring Data"
57+
},
58+
{
59+
"ids" : [ "spring.web" ],
60+
"displayName" : "Web"
61+
},
62+
{
63+
"ids" : [ "spring.web.rest" ],
64+
"displayName" : "REST"
65+
},
66+
{
67+
"ids" : [ "spring.web.rest.hypermedia" ],
68+
"displayName" : "Hypermedia"
69+
}
70+
]
71+
}

headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/stereotypes/ProjectBasedCatalogSourceTest.java

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,39 +52,47 @@ public class ProjectBasedCatalogSourceTest {
5252
@Autowired private SpringSymbolIndex indexer;
5353
@Autowired private SpringMetamodelIndex springIndex;
5454

55-
private File directory;
56-
private IJavaProject project;
55+
private File regularProjectDirectory;
56+
private File fallbackProjectDirectory;
57+
58+
private IJavaProject regularProject;
59+
private IJavaProject fallbackProject;
5760

5861
@BeforeEach
5962
public void setup() throws Exception {
6063
harness.intialize(null);
6164

62-
directory = new File(ProjectsHarness.class.getResource("/test-projects/test-stereotypes-support/").toURI());
63-
String projectDir = directory.toURI().toString();
65+
regularProjectDirectory = new File(ProjectsHarness.class.getResource("/test-projects/test-stereotypes-support/").toURI());
66+
String regularProjectDir = regularProjectDirectory.toURI().toString();
67+
68+
regularProject = projectFinder.find(new TextDocumentIdentifier(regularProjectDir)).get();
69+
70+
fallbackProjectDirectory = new File(ProjectsHarness.class.getResource("/test-projects/test-stereotypes-support-fallback/").toURI());
71+
String fallbackProjectDir = fallbackProjectDirectory.toURI().toString();
6472

65-
project = projectFinder.find(new TextDocumentIdentifier(projectDir)).get();
73+
fallbackProject = projectFinder.find(new TextDocumentIdentifier(fallbackProjectDir)).get();
6674

6775
CompletableFuture<Void> initProject = indexer.waitOperation();
6876
initProject.get(5, TimeUnit.SECONDS);
6977
}
7078

7179
@Test
7280
void testCatalogLookupFromSource() throws Exception {
73-
var source = new ProjectBasedCatalogSource(project);
81+
var source = new ProjectBasedCatalogSource(regularProject);
7482

7583
Stream<URL> sources = source.getSources();
7684
List<URL> list = sources.toList();
7785

78-
URL url1 = new File(directory, "src/main/resources/META-INF/jmolecules-stereotypes.json").toURI().toURL();
79-
URL url2 = new File(directory, "src/main/resources/META-INF/jmolecules-stereotype-groups.json").toURI().toURL();
86+
URL url1 = new File(regularProjectDirectory, "src/main/resources/META-INF/jmolecules-stereotypes.json").toURI().toURL();
87+
URL url2 = new File(regularProjectDirectory, "src/main/resources/META-INF/jmolecules-stereotype-groups.json").toURI().toURL();
8088

8189
assertTrue(list.contains(url1));
8290
assertTrue(list.contains(url2));
8391
}
8492

8593
@Test
8694
void testCatalogLookupFromLibraries() throws Exception {
87-
var source = new ProjectBasedCatalogSource(project);
95+
var source = new ProjectBasedCatalogSource(regularProject);
8896
var catalog = new JsonPathStereotypeCatalog(source);
8997

9098
StereotypeGroups groups = catalog.getGroups("org.jmolecules.ddd");
@@ -93,4 +101,15 @@ void testCatalogLookupFromLibraries() throws Exception {
93101
assertEquals("Domain-Driven Design", primary.getDisplayName());
94102
}
95103

104+
@Test
105+
void testCatalogDefaultLookupFromLanguageServer() throws Exception {
106+
var source = new ProjectBasedCatalogSource(fallbackProject);
107+
108+
Stream<URL> sources = source.getSources();
109+
List<URL> list = sources.toList();
110+
111+
assertEquals(1, list.size());
112+
assertTrue(list.get(0).toString().endsWith("jmolecules-stereotypes.json"));
113+
}
114+
96115
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# https://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
wrapperVersion=3.3.2
18+
distributionType=only-script
19+
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip

0 commit comments

Comments
 (0)