Skip to content

Commit

Permalink
Qute: fix generation of qute-i18n-examples
Browse files Browse the repository at this point in the history
- handle localized enums correctly
- fixes quarkusio#44366
  • Loading branch information
mkouba authored and bschuhmann committed Nov 16, 2024
1 parent 6a293d6 commit 38ea454
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,17 @@ public final class MessageBundleMethodBuildItem extends MultiBuildItem {
private final MethodInfo method;
private final String template;
private final boolean isDefaultBundle;
private final boolean hasGeneratedTemplate;

MessageBundleMethodBuildItem(String bundleName, String key, String templateId, MethodInfo method, String template,
boolean isDefaultBundle) {
boolean isDefaultBundle, boolean hasGeneratedTemplate) {
this.bundleName = bundleName;
this.key = key;
this.templateId = templateId;
this.method = method;
this.template = template;
this.isDefaultBundle = isDefaultBundle;
this.hasGeneratedTemplate = hasGeneratedTemplate;
}

public String getBundleName() {
Expand Down Expand Up @@ -54,6 +56,11 @@ public MethodInfo getMethod() {
return method;
}

/**
*
* @return {@code true} if there is a corresponding method declared on the message bundle interface
* @see #getMethod()
*/
public boolean hasMethod() {
return method != null;
}
Expand All @@ -79,6 +86,14 @@ public boolean isDefaultBundle() {
return isDefaultBundle;
}

/**
*
* @return {@code true} if the template was generated, e.g. a message bundle method for an enum
*/
public boolean hasGeneratedTemplate() {
return hasGeneratedTemplate;
}

/**
*
* @return the path
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -702,8 +702,22 @@ void generateExamplePropertiesFiles(List<MessageBundleMethodBuildItem> messageBu
List<MessageBundleMethodBuildItem> messages = entry.getValue();
messages.sort(Comparator.comparing(MessageBundleMethodBuildItem::getKey));
Path exampleProperties = generatedExamplesDir.resolve(entry.getKey() + ".properties");
Files.write(exampleProperties,
messages.stream().map(m -> m.getMethod().name() + "=" + m.getTemplate()).collect(Collectors.toList()));
List<String> lines = new ArrayList<>();
for (MessageBundleMethodBuildItem m : messages) {
if (m.hasMethod()) {
if (m.hasGeneratedTemplate()) {
// Skip messages with generated templates
continue;
}
// Keys are mapped to method names
lines.add(m.getMethod().name() + "=" + m.getTemplate());
} else {
// No corresponding method declared - use the key instead
// For example, there is no method for generated enum constant message keys
lines.add(m.getKey() + "=" + m.getTemplate());
}
}
Files.write(exampleProperties, lines);
}
}

Expand Down Expand Up @@ -992,6 +1006,7 @@ private String generateImplementation(MessageBundleBuildItem bundle, ClassInfo d
}
keyMap.put(key, new SimpleMessageMethod(method));

boolean generatedTemplate = false;
String messageTemplate = messageTemplates.get(method.name());
if (messageTemplate == null) {
messageTemplate = getMessageAnnotationValue(messageAnnotation);
Expand Down Expand Up @@ -1043,6 +1058,7 @@ private String generateImplementation(MessageBundleBuildItem bundle, ClassInfo d
}
generatedMessageTemplate.append("{/when}");
messageTemplate = generatedMessageTemplate.toString();
generatedTemplate = true;
}
}
}
Expand All @@ -1068,7 +1084,7 @@ private String generateImplementation(MessageBundleBuildItem bundle, ClassInfo d
}

MessageBundleMethodBuildItem messageBundleMethod = new MessageBundleMethodBuildItem(bundleName, key, templateId,
method, messageTemplate, defaultBundleInterface == null);
method, messageTemplate, defaultBundleInterface == null, generatedTemplate);
messageTemplateMethods
.produce(messageBundleMethod);

Expand Down Expand Up @@ -1139,8 +1155,7 @@ private void generateEnumConstantMessageMethod(ClassCreator bundleCreator, Strin
}

MessageBundleMethodBuildItem messageBundleMethod = new MessageBundleMethodBuildItem(bundleName, enumConstantKey,
templateId, null, messageTemplate,
defaultBundleInterface == null);
templateId, null, messageTemplate, defaultBundleInterface == null, true);
messageTemplateMethods.produce(messageBundleMethod);

MethodCreator enumConstantMethod = bundleCreator.getMethodCreator(enumConstantKey,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package io.quarkus.qute.deployment.i18n;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Properties;

import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.qute.i18n.Message;
import io.quarkus.qute.i18n.MessageBundle;
import io.quarkus.test.ProdBuildResults;
import io.quarkus.test.ProdModeTestResults;
import io.quarkus.test.QuarkusProdModeTest;

public class MessageBundleEnumExampleFileTest {

@RegisterExtension
static final QuarkusProdModeTest config = new QuarkusProdModeTest()
.withApplicationRoot(root -> root
.addClasses(Messages.class, MyEnum.class)
.addAsResource(new StringAsset("""
myEnum_ON=On
myEnum_OFF=Off
myEnum_UNDEFINED=Undefined
"""),
"messages/enu.properties"));

@ProdBuildResults
ProdModeTestResults testResults;

@Test
public void testExampleProperties() throws FileNotFoundException, IOException {
Path path = testResults.getBuildDir().resolve("qute-i18n-examples").resolve("enu.properties");
assertTrue(path.toFile().canRead());
Properties props = new Properties();
props.load(new FileInputStream(path.toFile()));
assertEquals(3, props.size());
assertTrue(props.containsKey("myEnum_ON"));
assertTrue(props.containsKey("myEnum_OFF"));
assertTrue(props.containsKey("myEnum_UNDEFINED"));
}

@MessageBundle(value = "enu", locale = "en")
public interface Messages {

// Replaced with:
// @Message("{#when myEnum}"
// + "{#is ON}{enu:myEnum_ON}"
// + "{#is OFF}{enu:myEnum_OFF}"
// + "{#is UNDEFINED}{enu:myEnum_UNDEFINED}"
// + "{/when}")
@Message
String myEnum(MyEnum myEnum);

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@
* There is a convenient way to localize enums.
* <p>
* If there is a message bundle method that accepts a single parameter of an enum type and has no message template defined then
* it
* receives a generated template:
* it receives a generated template:
*
* <pre>
* {#when enumParamName}
Expand Down

0 comments on commit 38ea454

Please sign in to comment.