Skip to content

Commit b4ad7df

Browse files
committed
feat: Initialize roq support
Signed-off-by: azerr <[email protected]>
1 parent 972c3a0 commit b4ad7df

19 files changed

+863
-193
lines changed

gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ gradleVersion=8.6
1919
channel=nightly
2020
quarkusVersion=3.15.1
2121
lsp4mpVersion=0.13.0
22-
quarkusLsVersion=0.20.0
23-
quteLsVersion=0.20.0
22+
quarkusLsVersion=0.21.0-SNAPSHOT
23+
quteLsVersion=0.21.0-SNAPSHOT
2424
# Opt-out flag for bundling Kotlin standard library -> https://jb.gg/intellij-platform-kotlin-stdlib
2525
kotlin.stdlib.default.dependency=false
2626
# Enable Gradle Configuration Cache -> https://docs.gradle.org/current/userguide/configuration_cache.html

src/main/java/com/redhat/devtools/intellij/qute/lang/QuteLanguageSubstitutor.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,13 @@
3636
* </ul>
3737
*/
3838
public class QuteLanguageSubstitutor extends LanguageSubstitutor {
39-
protected boolean isTemplate(VirtualFile file, Module module) {
40-
return isQuteTemplate(file, module) &&
41-
ModuleRootManager.getInstance(module).getFileIndex().isInSourceContent(file);
39+
40+
private static boolean isTemplate(VirtualFile file, Module module) {
41+
return isQuteTemplate(file, module) /*&&
42+
ModuleRootManager.getInstance(module).getFileIndex().isInSourceContent(file)*/;
4243
}
4344

44-
protected boolean isQuteModule(Module module) {
45+
private static boolean isQuteModule(Module module) {
4546
OrderEnumerator libraries = ModuleRootManager.getInstance(module).orderEntries().librariesOnly();
4647
return libraries.process(new RootPolicy<Boolean>() {
4748
@Override

src/main/java/com/redhat/devtools/intellij/qute/psi/internal/QuteJavaConstants.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
*******************************************************************************/
1212
package com.redhat.devtools.intellij.qute.psi.internal;
1313

14+
import java.util.Collection;
15+
import java.util.List;
16+
1417
/**
1518
* Qute Java constants.
1619
*
@@ -30,6 +33,8 @@ public class QuteJavaConstants {
3033

3134
public static final String TEMPLATE_INSTANCE_INTERFACE = "io.quarkus.qute.TemplateInstance";
3235

36+
public static Collection<String> QUTE_MAVEN_COORDS = List.of("io.quarkus:quarkus-qute", "io.quarkus.qute:qute-core");
37+
3338
public static final String ENGINE_BUILDER_CLASS = "io.quarkus.qute.EngineBuilder";
3439

3540
public static final String VALUE_ANNOTATION_NAME = "value";
@@ -64,6 +69,8 @@ public class QuteJavaConstants {
6469

6570
public static final String TEMPLATE_EXTENSION_ANNOTATION_MATCH_NAME = "matchName";
6671

72+
public static final String TEMPLATE_EXTENSION_ANNOTATION_MATCH_NAMES = "matchNames";
73+
6774
// @TemplateData
6875

6976
public static final String TEMPLATE_DATA_ANNOTATION = "io.quarkus.qute.TemplateData";
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2024 Red Hat Inc. and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* which accompanies this distribution, and is available at
5+
* http://www.eclipse.org/legal/epl-v20.html
6+
*
7+
* SPDX-License-Identifier: EPL-2.0
8+
*
9+
* Contributors:
10+
* Red Hat Inc. - initial API and implementation
11+
*******************************************************************************/
12+
package com.redhat.devtools.intellij.qute.psi.internal.extensions.roq;
13+
14+
import com.intellij.openapi.progress.ProgressIndicator;
15+
import com.intellij.psi.PsiAnnotation;
16+
import com.intellij.psi.PsiClass;
17+
import com.intellij.psi.PsiElement;
18+
import com.redhat.devtools.intellij.qute.psi.template.datamodel.AbstractAnnotationTypeReferenceDataModelProvider;
19+
import com.redhat.devtools.intellij.qute.psi.template.datamodel.SearchContext;
20+
import com.redhat.devtools.intellij.qute.psi.utils.AnnotationUtils;
21+
import com.redhat.qute.commons.datamodel.resolvers.ValueResolverInfo;
22+
import com.redhat.qute.commons.datamodel.resolvers.ValueResolverKind;
23+
import org.apache.commons.lang3.StringUtils;
24+
import org.jetbrains.annotations.Nullable;
25+
26+
import java.util.List;
27+
import java.util.logging.Logger;
28+
29+
import static com.redhat.devtools.intellij.qute.psi.internal.QuteJavaConstants.VALUE_ANNOTATION_NAME;
30+
import static com.redhat.devtools.intellij.qute.psi.internal.extensions.roq.RoqJavaConstants.DATA_MAPPING_ANNOTATION;
31+
32+
/**
33+
* Roq @DataMapping annotation support.
34+
*
35+
* @author Angelo ZERR
36+
*/
37+
public class DataMappingSupport extends AbstractAnnotationTypeReferenceDataModelProvider {
38+
39+
private static final Logger LOGGER = Logger.getLogger(DataMappingSupport.class.getName());
40+
41+
private static final String INJECT_NAMESPACE = "inject";
42+
43+
private static final String[] ANNOTATION_NAMES = {DATA_MAPPING_ANNOTATION};
44+
45+
@Override
46+
protected String[] getAnnotationNames() {
47+
return ANNOTATION_NAMES;
48+
}
49+
50+
@Override
51+
protected void processAnnotation(PsiElement javaElement, PsiAnnotation annotation, String annotationName,
52+
SearchContext context, ProgressIndicator monitor) {
53+
if (!(javaElement instanceof PsiClass)) {
54+
return;
55+
}
56+
// @DataMapping(value = "events", parentArray = true)
57+
// public record Events(List<Event> list) {
58+
// becomes --> inject:events
59+
60+
PsiClass type = (PsiClass) javaElement;
61+
String value = getDataMappingAnnotationValue(type);
62+
if (StringUtils.isNoneBlank(value)) {
63+
collectResolversForInject(type, value, context.getDataModelProject().getValueResolvers());
64+
}
65+
}
66+
67+
@Nullable
68+
private static String getDataMappingAnnotationValue(PsiClass javaElement) {
69+
PsiAnnotation namedAnnotation = AnnotationUtils.getAnnotation(javaElement,
70+
DATA_MAPPING_ANNOTATION);
71+
if (namedAnnotation != null) {
72+
return AnnotationUtils.getAnnotationMemberValue(namedAnnotation, VALUE_ANNOTATION_NAME);
73+
}
74+
return null;
75+
}
76+
77+
private static void collectResolversForInject(PsiClass type, String named, List<ValueResolverInfo> resolvers) {
78+
ValueResolverInfo resolver = new ValueResolverInfo();
79+
resolver.setNamed(named);
80+
resolver.setSourceType(type.getQualifiedName());
81+
resolver.setSignature(type.getQualifiedName());
82+
resolver.setNamespace(INJECT_NAMESPACE);
83+
resolver.setKind(ValueResolverKind.InjectedBean);
84+
resolvers.add(resolver);
85+
}
86+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2024 Red Hat Inc. and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* which accompanies this distribution, and is available at
5+
* http://www.eclipse.org/legal/epl-v20.html
6+
*
7+
* SPDX-License-Identifier: EPL-2.0
8+
*
9+
* Contributors:
10+
* Red Hat Inc. - initial API and implementation
11+
*******************************************************************************/
12+
package com.redhat.devtools.intellij.qute.psi.internal.extensions.roq;
13+
14+
import java.util.Arrays;
15+
16+
17+
import com.intellij.java.library.JavaLibraryUtil;
18+
import com.intellij.openapi.progress.ProgressIndicator;
19+
import com.intellij.util.Query;
20+
import com.redhat.devtools.intellij.qute.psi.template.datamodel.AbstractDataModelProvider;
21+
import com.redhat.devtools.intellij.qute.psi.template.datamodel.SearchContext;
22+
import com.redhat.qute.commons.datamodel.DataModelParameter;
23+
import com.redhat.qute.commons.datamodel.DataModelTemplate;
24+
import com.redhat.qute.commons.datamodel.DataModelTemplateMatcher;
25+
26+
/**
27+
* Inject 'site' and 'page' as data model parameters for all Qute templates
28+
* which belong to a Roq application.
29+
*/
30+
public class RoqDataModelProvider extends AbstractDataModelProvider {
31+
32+
@Override
33+
public void beginSearch(SearchContext context, ProgressIndicator monitor) {
34+
if (!RoqUtils.isRoqProject(context.getJavaProject())) {
35+
// It is not a Roq application, don't inject site and page.
36+
return;
37+
}
38+
//quarkus-roq-frontmatter
39+
40+
DataModelTemplate<DataModelParameter> roqTemplate = new DataModelTemplate<DataModelParameter>();
41+
roqTemplate.setTemplateMatcher(new DataModelTemplateMatcher(Arrays.asList("**/**")));
42+
43+
// site
44+
DataModelParameter site = new DataModelParameter();
45+
site.setKey("site");
46+
site.setSourceType(RoqJavaConstants.SITE_CLASS);
47+
roqTemplate.addParameter(site);
48+
49+
// page
50+
DataModelParameter page = new DataModelParameter();
51+
page.setKey("page");
52+
page.setSourceType(RoqJavaConstants.PAGE_CLASS);
53+
roqTemplate.addParameter(page);
54+
55+
context.getDataModelProject().getTemplates().add(roqTemplate);
56+
}
57+
58+
@Override
59+
public void collectDataModel(Object match, SearchContext context, ProgressIndicator monitor) {
60+
// Do nothing
61+
}
62+
63+
@Override
64+
protected String[] getPatterns() {
65+
return null;
66+
}
67+
68+
@Override
69+
protected Query<? extends Object> createSearchPattern(SearchContext context, String pattern) {
70+
return null;
71+
}
72+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2024 Red Hat Inc. and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* which accompanies this distribution, and is available at
5+
* http://www.eclipse.org/legal/epl-v20.html
6+
*
7+
* SPDX-License-Identifier: EPL-2.0
8+
*
9+
* Contributors:
10+
* Red Hat Inc. - initial API and implementation
11+
*******************************************************************************/
12+
package com.redhat.devtools.intellij.qute.psi.internal.extensions.roq;
13+
14+
import java.util.Collection;
15+
import java.util.List;
16+
17+
/**
18+
* Roq Java constants.
19+
*
20+
* @author Angelo ZERR
21+
*
22+
*/
23+
public class RoqJavaConstants {
24+
25+
private RoqJavaConstants() {
26+
}
27+
28+
public static final String ROQ_ARTIFACT_ID = "quarkus-roq-frontmatter";
29+
30+
public static final Collection<String> ROQ_MAVEN_COORS = List.of("io.quarkiverse.roq:quarkus-roq-frontmatter");
31+
32+
public static final String DATA_MAPPING_ANNOTATION = "io.quarkiverse.roq.data.runtime.annotations.DataMapping";
33+
34+
public static final String SITE_CLASS = "io.quarkiverse.roq.frontmatter.runtime.model.Site";
35+
36+
public static final String PAGE_CLASS = "io.quarkiverse.roq.frontmatter.runtime.model.Page";
37+
38+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2024 Red Hat Inc. and others.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7+
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
8+
*
9+
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10+
*
11+
* Contributors:
12+
* Red Hat Inc. - initial API and implementation
13+
*******************************************************************************/
14+
package com.redhat.devtools.intellij.qute.psi.internal.extensions.roq;
15+
16+
import java.util.List;
17+
18+
19+
import com.intellij.java.library.JavaLibraryUtil;
20+
import com.intellij.openapi.module.Module;
21+
import com.intellij.openapi.vfs.VirtualFile;
22+
import com.redhat.devtools.intellij.quarkus.QuarkusModuleUtil;
23+
import com.redhat.devtools.intellij.qute.psi.template.rootpath.ITemplateRootPathProvider;
24+
import com.redhat.devtools.intellij.qute.psi.utils.PsiQuteProjectUtils;
25+
import com.redhat.devtools.intellij.qute.psi.utils.PsiTypeUtils;
26+
import com.redhat.devtools.lsp4ij.LSPIJUtils;
27+
import com.redhat.qute.commons.TemplateRootPath;
28+
import org.slf4j.Logger;
29+
import org.slf4j.LoggerFactory;
30+
31+
/**
32+
* Roq template root path provider for Roq project.
33+
*/
34+
public class RoqTemplateRootPathProvider implements ITemplateRootPathProvider {
35+
36+
private static final String ORIGIN = "roq";
37+
38+
private static final String[] TEMPLATES_BASE_DIRS = { "templates/", "content/", "src/main/resources/content/" };
39+
40+
@Override
41+
public boolean isApplicable(Module javaProject) {
42+
return RoqUtils.isRoqProject(javaProject);
43+
}
44+
45+
@Override
46+
public void collectTemplateRootPaths(Module javaProject, List<TemplateRootPath> rootPaths) {
47+
VirtualFile moduleDir = QuarkusModuleUtil.getModuleDirPath(javaProject);
48+
if (moduleDir != null) {
49+
// templates
50+
String templateBaseDir = LSPIJUtils.toUri(moduleDir).resolve("templates").toASCIIString();
51+
rootPaths.add(new TemplateRootPath(templateBaseDir, ORIGIN));
52+
// content
53+
String contentBaseDir = LSPIJUtils.toUri(moduleDir).resolve("content").toASCIIString();
54+
rootPaths.add(new TemplateRootPath(contentBaseDir, ORIGIN));
55+
}
56+
// src/main/resources/content
57+
VirtualFile resourcesContentDir = PsiQuteProjectUtils.findBestResourcesDir(javaProject, "content");
58+
if (resourcesContentDir != null) {
59+
String contentBaseDir = LSPIJUtils.toUri(resourcesContentDir).resolve("content").toASCIIString();
60+
rootPaths.add(new TemplateRootPath(contentBaseDir, ORIGIN));
61+
}
62+
}
63+
64+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2024 Red Hat Inc. and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* which accompanies this distribution, and is available at
5+
* http://www.eclipse.org/legal/epl-v20.html
6+
*
7+
* SPDX-License-Identifier: EPL-2.0
8+
*
9+
* Contributors:
10+
* Red Hat Inc. - initial API and implementation
11+
*******************************************************************************/
12+
package com.redhat.devtools.intellij.qute.psi.internal.extensions.roq;
13+
14+
import com.intellij.java.library.JavaLibraryUtil;
15+
import com.intellij.openapi.module.Module;
16+
import com.intellij.openapi.module.ModuleUtilCore;
17+
import org.jetbrains.annotations.NotNull;
18+
19+
import java.util.HashSet;
20+
import java.util.Set;
21+
22+
/**
23+
* Roq Utilities.
24+
*/
25+
public class RoqUtils {
26+
27+
/**
28+
* Returns true if the given module is a Roq project and false otherwise.
29+
*
30+
* @param module the module.
31+
* @return true if the given module is a Roq project and false otherwise.
32+
*/
33+
public static boolean isRoqProject(@NotNull Module module) {
34+
if (JavaLibraryUtil.hasAnyLibraryJar(module, RoqJavaConstants.ROQ_MAVEN_COORS)) {
35+
return true;
36+
}
37+
38+
Set<Module> projectDependencies = new HashSet<>();
39+
ModuleUtilCore.getDependencies(module, projectDependencies);
40+
return projectDependencies
41+
.stream()
42+
.anyMatch(m -> RoqJavaConstants.ROQ_ARTIFACT_ID.equals(m.getName()));
43+
}
44+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2024 Red Hat Inc. and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* which accompanies this distribution, and is available at
5+
* http://www.eclipse.org/legal/epl-v20.html
6+
*
7+
* SPDX-License-Identifier: EPL-2.0
8+
*
9+
* Contributors:
10+
* Red Hat Inc. - initial API and implementation
11+
*******************************************************************************/
12+
package com.redhat.devtools.intellij.qute.psi.internal.extensions.webbundler;
13+
14+
import java.util.Collection;
15+
import java.util.List;
16+
17+
/**
18+
* Web Bundler Java constants.
19+
*
20+
* @author Angelo ZERR
21+
*
22+
*/
23+
public class WebBundlerJavaConstants {
24+
25+
private WebBundlerJavaConstants() {
26+
}
27+
28+
public static final Collection<String> WEB_BUNDLER_MAVEN_COORS = List.of("io.quarkiverse.web-bundler:quarkus-roq-frontmatter");
29+
30+
public static final String BUNDLE_CLASS = "io.quarkiverse.web.bundler.runtime.Bundle";
31+
32+
}

0 commit comments

Comments
 (0)