Skip to content

Commit

Permalink
Merge pull request #14584 from mkouba/qute-fix-multiple-namespace-ext…
Browse files Browse the repository at this point in the history
…ension-single-class

Qute - support multiple namespace extension methods on the same class
  • Loading branch information
geoand authored Jan 26, 2021
2 parents 778933e + feafa1c commit 9294528
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,7 @@ public boolean test(String name) {
generatedTypes.addAll(generator.getGeneratedTypes());

ExtensionMethodGenerator extensionMethodGenerator = new ExtensionMethodGenerator(index, classOutput);
Map<DotName, List<TemplateExtensionMethodBuildItem>> classToNamespaceExtensions = new HashMap<>();
Map<DotName, Map<String, List<TemplateExtensionMethodBuildItem>>> classToNamespaceExtensions = new HashMap<>();
Map<String, DotName> namespaceToClass = new HashMap<>();

for (TemplateExtensionMethodBuildItem templateExtension : templateExtensionMethods) {
Expand All @@ -864,17 +864,23 @@ public boolean test(String name) {
DotName declaringClassName = templateExtension.getMethod().declaringClass().name();
DotName namespaceClassName = namespaceToClass.get(templateExtension.getNamespace());
if (namespaceClassName == null) {
namespaceToClass.put(templateExtension.getNamespace(), declaringClassName);
namespaceToClass.put(templateExtension.getNamespace(), namespaceClassName);
} else if (!namespaceClassName.equals(declaringClassName)) {
throw new IllegalStateException("Template extension methods that share the namespace "
+ templateExtension.getNamespace() + " must be declared on the same class; but declared on "
+ namespaceClassName + " and " + declaringClassName);
}
List<TemplateExtensionMethodBuildItem> namespaceMethods = classToNamespaceExtensions
Map<String, List<TemplateExtensionMethodBuildItem>> namespaceToExtensions = classToNamespaceExtensions
.get(declaringClassName);
if (namespaceToExtensions == null) {
namespaceToExtensions = new HashMap<>();
classToNamespaceExtensions.put(declaringClassName, namespaceToExtensions);
}
List<TemplateExtensionMethodBuildItem> namespaceMethods = namespaceToExtensions
.get(templateExtension.getNamespace());
if (namespaceMethods == null) {
namespaceMethods = new ArrayList<>();
classToNamespaceExtensions.put(declaringClassName, namespaceMethods);
namespaceToExtensions.put(templateExtension.getNamespace(), namespaceMethods);
}
namespaceMethods.add(templateExtension);
} else {
Expand All @@ -885,15 +891,19 @@ public boolean test(String name) {
}

// Generate a namespace resolver for extension methods declared on the same class
for (Entry<DotName, List<TemplateExtensionMethodBuildItem>> entry : classToNamespaceExtensions.entrySet()) {
List<TemplateExtensionMethodBuildItem> methods = entry.getValue();
// Methods with higher priority take precedence
methods.sort(Comparator.comparingInt(TemplateExtensionMethodBuildItem::getPriority).reversed());
try (NamespaceResolverCreator namespaceResolverCreator = extensionMethodGenerator
.createNamespaceResolver(methods.get(0).getMethod().declaringClass(), methods.get(0).getNamespace())) {
try (ResolveCreator resolveCreator = namespaceResolverCreator.implementResolve()) {
for (TemplateExtensionMethodBuildItem method : methods) {
resolveCreator.addMethod(method.getMethod(), method.getMatchName(), method.getMatchRegex());
for (Entry<DotName, Map<String, List<TemplateExtensionMethodBuildItem>>> entry1 : classToNamespaceExtensions
.entrySet()) {
Map<String, List<TemplateExtensionMethodBuildItem>> namespaceToMethods = entry1.getValue();
for (Entry<String, List<TemplateExtensionMethodBuildItem>> entry2 : namespaceToMethods.entrySet()) {
List<TemplateExtensionMethodBuildItem> methods = entry2.getValue();
// Methods with higher priority take precedence
methods.sort(Comparator.comparingInt(TemplateExtensionMethodBuildItem::getPriority).reversed());
try (NamespaceResolverCreator namespaceResolverCreator = extensionMethodGenerator
.createNamespaceResolver(methods.get(0).getMethod().declaringClass(), entry2.getKey())) {
try (ResolveCreator resolveCreator = namespaceResolverCreator.implementResolve()) {
for (TemplateExtensionMethodBuildItem method : methods) {
resolveCreator.addMethod(method.getMethod(), method.getMatchName(), method.getMatchRegex());
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static io.quarkus.qute.TemplateExtension.ANY;
import static org.junit.jupiter.api.Assertions.assertEquals;

import javax.enterprise.event.TransactionPhase;
import javax.inject.Inject;

import org.jboss.shrinkwrap.api.ShrinkWrap;
Expand Down Expand Up @@ -36,6 +37,8 @@ public void testTemplateExtensions() {
engine.parse("{str:foolish('hello')}").render());
assertEquals("ONE=ONE",
engine.parse("{MyEnum:ONE}={MyEnum:one}").render());
assertEquals("IN_PROGRESS=0",
engine.parse("{txPhase:IN_PROGRESS}={txPhase:IN_PROGRESS.ordinal}").render());
}

@TemplateExtension(namespace = "str")
Expand Down Expand Up @@ -70,6 +73,11 @@ static MyEnum getVal(String val) {
return MyEnum.valueOf(val.toUpperCase());
}

@TemplateExtension(namespace = "txPhase", matchName = "*")
static TransactionPhase enumValue(String value) {
return TransactionPhase.valueOf(value);
}

}

}

0 comments on commit 9294528

Please sign in to comment.