Skip to content

Commit

Permalink
fix: respect basePath in @CheckedTemplate to find templates
Browse files Browse the repository at this point in the history
Signed-off-by: Fred Bricon <[email protected]>
  • Loading branch information
fbricon committed Sep 18, 2023
1 parent db1ab9b commit 735f26d
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public class QuteJavaConstants {
public static final String OLD_CHECKED_TEMPLATE_ANNOTATION = "io.quarkus.qute.api.CheckedTemplate";

public static final String CHECKED_TEMPLATE_ANNOTATION_IGNORE_FRAGMENTS = "ignoreFragments";
public static final String CHECKED_TEMPLATE_ANNOTATION_BASE_PATH = "basePath";

// @TemplateExtension

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
import static com.redhat.devtools.intellij.qute.psi.internal.QuteJavaConstants.OLD_CHECKED_TEMPLATE_ANNOTATION;
import static com.redhat.devtools.intellij.qute.psi.internal.QuteJavaConstants.CHECKED_TEMPLATE_ANNOTATION_IGNORE_FRAGMENTS;
import static com.redhat.devtools.intellij.qute.psi.internal.QuteJavaConstants.TEMPLATE_CLASS;
import static com.redhat.devtools.intellij.qute.psi.internal.template.datamodel.CheckedTemplateSupport.getBasePath;
import static com.redhat.devtools.intellij.qute.psi.internal.template.datamodel.CheckedTemplateSupport.isIgnoreFragments;

/**
* Abstract class which collects {@link PsiMethod} or
Expand Down Expand Up @@ -108,7 +110,7 @@ public void visitField(PsiField node) {
.getLocationExpressionFromConstructorParameter(node.getName());
}
String fieldName = node.getName();
collectTemplateLink(node, locationExpression, getTypeDeclaration(node), null, fieldName, false);
collectTemplateLink(null, node, locationExpression, getTypeDeclaration(node), null, fieldName, false);
}
super.visitField(node);
}
Expand Down Expand Up @@ -137,67 +139,39 @@ public void visitClass(PsiClass node) {
// public static class Templates {
// public static native TemplateInstance book(Book book);
boolean ignoreFragments = isIgnoreFragments(annotation);
String basePath = getBasePath(annotation);
for(PsiMethod method : node.getMethods()) {
collectTemplateLink(method, node, ignoreFragments );
collectTemplateLink(basePath, method, node, ignoreFragments );
}
}
}
super.visitClass(node);
levelTypeDecl--;
}

/**
* Returns true if @CheckedTemplate annotation declares that fragment must be
* ignored and false otherwise.
*
* <code>
* @CheckedTemplate(ignoreFragments=true)
* </code>
*
* @param checkedTemplateAnnotation the CheckedTemplate annotation.
*
* @return true if @CheckedTemplate annotation declares that fragment must be
* ignored and false otherwise.
*/
private static boolean isIgnoreFragments(PsiAnnotation checkedTemplateAnnotation) {
Boolean ignoreFragment = null;
try {
for(PsiNameValuePair pair : checkedTemplateAnnotation.getParameterList().getAttributes()) {
if (CHECKED_TEMPLATE_ANNOTATION_IGNORE_FRAGMENTS.equalsIgnoreCase(pair.getAttributeName())) {
ignoreFragment = AnnotationUtils.getValueAsBoolean(pair);
}
}
} catch (IndexNotReadyException | ProcessCanceledException | CancellationException e) {
throw e;
} catch (Exception e) {
// Do nothing
}
return ignoreFragment != null ? ignoreFragment.booleanValue() : false;
}

private static PsiClass getTypeDeclaration(PsiElement node) {
return PsiTreeUtil.getParentOfType(node, PsiClass.class);
}


private void collectTemplateLink(PsiMethod methodDeclaration, PsiClass type, boolean ignoreFragments) {
private void collectTemplateLink(String basePath, PsiMethod methodDeclaration, PsiClass type, boolean ignoreFragments) {
String className = null;
boolean innerClass = levelTypeDecl > 1;
if (innerClass) {
className = PsiTypeUtils.getSimpleClassName(typeRoot.getName());
}
String methodName = methodDeclaration.getName();
collectTemplateLink(methodDeclaration, null, type, className, methodName, ignoreFragments );
collectTemplateLink(basePath, methodDeclaration, null, type, className, methodName, ignoreFragments );
}

private void collectTemplateLink(PsiElement fieldOrMethod, PsiLiteralValue locationAnnotation, PsiClass type, String className,
private void collectTemplateLink(String basePath, PsiElement fieldOrMethod, PsiLiteralValue locationAnnotation, PsiClass type, String className,
String fieldOrMethodName, boolean ignoreFragment ) {
try {
String location = locationAnnotation != null && locationAnnotation.getValue() instanceof String ? (String) locationAnnotation.getValue() : null;
Module project = utils.getModule();
TemplatePathInfo templatePathInfo = location != null
? PsiQuteProjectUtils.getTemplatePath(null, location, ignoreFragment)
: PsiQuteProjectUtils.getTemplatePath(className, fieldOrMethodName, ignoreFragment);
? PsiQuteProjectUtils.getTemplatePath(basePath, null, location, ignoreFragment)
: PsiQuteProjectUtils.getTemplatePath(basePath, className, fieldOrMethodName, ignoreFragment);

VirtualFile templateFile = null;
if (location == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ protected void processAnnotation(PsiElement javaElement, PsiAnnotation checkedTe
if (javaElement instanceof PsiClass) {
PsiClass type = (PsiClass) javaElement;
boolean ignoreFragments = isIgnoreFragments(checkedTemplateAnnotation);
collectDataModelTemplateForCheckedTemplate(type, ignoreFragments, context.getTypeResolver(type),
String basePath = getBasePath(checkedTemplateAnnotation);
collectDataModelTemplateForCheckedTemplate(type, basePath, ignoreFragments, context.getTypeResolver(type),
context.getDataModelProject().getTemplates(), monitor);
}
}
Expand All @@ -96,7 +97,7 @@ protected void processAnnotation(PsiElement javaElement, PsiAnnotation checkedTe
* ignored and false otherwise.
* @CheckedTemplate(ignoreFragments=true) </code>
*/
private static boolean isIgnoreFragments(PsiAnnotation checkedTemplateAnnotation) {
public static boolean isIgnoreFragments(PsiAnnotation checkedTemplateAnnotation) {
Boolean ignoreFragment = null;
try {
for (PsiNameValuePair pair : checkedTemplateAnnotation.getParameterList().getAttributes()) {
Expand All @@ -112,15 +113,32 @@ private static boolean isIgnoreFragments(PsiAnnotation checkedTemplateAnnotation
return ignoreFragment != null ? ignoreFragment.booleanValue() : false;
}

public static String getBasePath(PsiAnnotation checkedTemplateAnnotation) {
String basePath = "";
try {
for (PsiNameValuePair pair : checkedTemplateAnnotation.getParameterList().getAttributes()) {
if (CHECKED_TEMPLATE_ANNOTATION_BASE_PATH.equalsIgnoreCase(pair.getAttributeName())) {
basePath = pair.getLiteralValue();
}
}
} catch (IndexNotReadyException | ProcessCanceledException | CancellationException e) {
throw e;
} catch (Exception e) {
// Do nothing
}
return basePath;
}

/**
* Collect data model template from @CheckedTemplate.
*
* @param type the Java type.
* @param basePath the base path relative to the templates root
* @param ignoreFragments true if fragments must be ignored and false otherwise.
* @param templates the data model templates to update with collect of template.
* @param monitor the progress monitor.
*/
private static void collectDataModelTemplateForCheckedTemplate(PsiClass type, boolean ignoreFragments, ITypeResolver typeResolver,
private static void collectDataModelTemplateForCheckedTemplate(PsiClass type, String basePath, boolean ignoreFragments, ITypeResolver typeResolver,
List<DataModelTemplate<DataModelParameter>> templates, ProgressIndicator monitor) {
boolean innerClass = type.getContainingClass() != null;
String className = !innerClass ? null
Expand All @@ -131,7 +149,7 @@ private static void collectDataModelTemplateForCheckedTemplate(PsiClass type, bo
PsiMethod[] methods = type.getMethods();
for (PsiMethod method : methods) {
// src/main/resources/templates/${className}/${methodName}.qute.html
TemplatePathInfo templatePathInfo = getTemplatePath(className, method.getName(), ignoreFragments);
TemplatePathInfo templatePathInfo = getTemplatePath(basePath, className, method.getName(), ignoreFragments);

// Get or create template
String templateUri = templatePathInfo.getTemplateUri();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ private static DataModelTemplate<DataModelParameter> createTemplateDataModel(Psi
String location = locationFromConstructorParameter != null ? locationFromConstructorParameter : getLocation(field);
String fieldName = field.getName();
// src/main/resources/templates/${methodName}.qute.html
String templateUri = getTemplatePath(null, location != null ? location : fieldName, true).getTemplateUri();
String templateUri = getTemplatePath(null,null, location != null ? location : fieldName, true).getTemplateUri();

// Create template data model with:
// - template uri : Qute template file which must be bind with data model.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,30 @@ public static boolean hasQuteSupport(Module javaProject) {
return PsiTypeUtils.findType(javaProject, QuteJavaConstants.ENGINE_BUILDER_CLASS) != null;
}

public static String getTemplatePath(String className, String methodOrFieldName) {
public static String getTemplatePath(String basePath, String className, String methodOrFieldName) {
StringBuilder path = new StringBuilder(TEMPLATES_BASE_DIR);
if (basePath != null && !basePath.isBlank()){
path.append(basePath.startsWith("/")? basePath.substring(1): basePath);
if (!basePath.endsWith("/")) {
path.append('/');
}
}
if (className != null) {
path.append(className);
path.append('/');
}
return path.append(methodOrFieldName).toString();
}

public static TemplatePathInfo getTemplatePath(String className, String methodOrFieldName, boolean ignoreFragments) {
public static TemplatePathInfo getTemplatePath(String basePath, String className, String methodOrFieldName, boolean ignoreFragments) {
String fragmentId = null;
StringBuilder templateUri = new StringBuilder(TEMPLATES_BASE_DIR);
if (basePath != null && !basePath.isBlank()){
templateUri.append(basePath.startsWith("/")? basePath.substring(1): basePath);
if (!basePath.endsWith("/")) {
templateUri.append('/');
}
}
if (className != null) {
templateUri.append(className);
templateUri.append('/');
Expand Down

0 comments on commit 735f26d

Please sign in to comment.