Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import org.springframework.util.StringUtils;

import jakarta.annotation.Nonnull;

import java.text.MessageFormat;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
Expand All @@ -25,15 +27,23 @@ public void addMessageSource(MessageSource source) {
messageSources.add(source);
}

private String formatMessage(String message, Object[] args, Locale locale) {
if (message == null || message.isBlank() || args == null || args.length == 0) {
return message;
}
MessageFormat messageFormat = new MessageFormat(message, locale);
return messageFormat.format(args);
}

@Override
public String getMessage(@Nonnull String code, Object[] args, String defaultMessage, @Nonnull Locale locale) {
for (MessageSource messageSource : messageSources) {
String result = messageSource.getMessage(code, args, null, locale);
if (StringUtils.hasText(result)) {
return result;
return formatMessage(result, args, locale);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里不需要再formatMessage了吧? 下同.

}
}
return defaultMessage;
return formatMessage(defaultMessage, args, locale);
}

@Override
Expand All @@ -43,7 +53,7 @@ public String getMessage(@Nonnull String code, Object[] args, @Nonnull Locale lo
try {
String result = messageSource.getMessage(code, args, locale);
if (StringUtils.hasText(result)) {
return result;
return formatMessage(result, args, locale);
}
} catch (NoSuchMessageException ignore) {

Expand All @@ -59,7 +69,7 @@ public String getMessage(@Nonnull MessageSourceResolvable resolvable, @Nonnull L
try {
String result = messageSource.getMessage(resolvable, locale);
if (StringUtils.hasText(result)) {
return result;
return formatMessage(result, resolvable.getArguments(), locale);
}
} catch (NoSuchMessageException ignore) {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
package org.hswebframework.web.starter.i18n;

import org.junit.Test;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceResolvable;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.support.StaticMessageSource;

import java.util.Locale;

import static org.junit.Assert.*;

public class CompositeMessageSourceTest {

@Test
public void testFormatMessageWithArgs() {
CompositeMessageSource compositeMessageSource = new CompositeMessageSource();

StaticMessageSource staticMessageSource = new StaticMessageSource();
staticMessageSource.addMessage("message.test", Locale.ENGLISH, "Hello {0}, your code is {1}");
staticMessageSource.addMessage("message.test", Locale.CHINESE, "你好 {0}, 你的代码是 {1}");

compositeMessageSource.addMessageSource(staticMessageSource);

// 测试英文带参数
String result = compositeMessageSource.getMessage(
"message.test",
new Object[]{"World", "12345"},
null,
Locale.ENGLISH
);
assertEquals("Hello World, your code is 12345", result);

// 测试中文带参数
result = compositeMessageSource.getMessage(
"message.test",
new Object[]{"张三", "67890"},
null,
Locale.CHINESE
);
assertEquals("你好 张三, 你的代码是 67890", result);
}

@Test
public void testFormatDefaultMessageWithArgs() {
CompositeMessageSource compositeMessageSource = new CompositeMessageSource();

// 没有添加任何消息源,应该返回格式化后的 defaultMessage
String result = compositeMessageSource.getMessage(
"message.not.found",
new Object[]{"device-001", "connection timeout"},
"Send failed, device: {0}, error: {1}",
Locale.ENGLISH
);
assertEquals("Send failed, device: device-001, error: connection timeout", result);
}

@Test
public void testFormatMessageWithoutArgs() {
CompositeMessageSource compositeMessageSource = new CompositeMessageSource();

StaticMessageSource staticMessageSource = new StaticMessageSource();
staticMessageSource.addMessage("message.simple", Locale.ENGLISH, "Simple message");

compositeMessageSource.addMessageSource(staticMessageSource);

String result = compositeMessageSource.getMessage(
"message.simple",
null,
null,
Locale.ENGLISH
);
assertEquals("Simple message", result);
}

@Test
public void testFormatMessageWithEmptyArgs() {
CompositeMessageSource compositeMessageSource = new CompositeMessageSource();

StaticMessageSource staticMessageSource = new StaticMessageSource();
staticMessageSource.addMessage("message.simple", Locale.ENGLISH, "Simple message");

compositeMessageSource.addMessageSource(staticMessageSource);

String result = compositeMessageSource.getMessage(
"message.simple",
new Object[]{},
null,
Locale.ENGLISH
);
assertEquals("Simple message", result);
}

@Test
public void testGetMessageWithLocaleOnly() {
CompositeMessageSource compositeMessageSource = new CompositeMessageSource();

StaticMessageSource staticMessageSource = new StaticMessageSource();
staticMessageSource.addMessage("message.test", Locale.ENGLISH, "Hello {0}");

compositeMessageSource.addMessageSource(staticMessageSource);

String result = compositeMessageSource.getMessage(
"message.test",
new Object[]{"World"},
Locale.ENGLISH
);
assertEquals("Hello World", result);
}

@Test(expected = NoSuchMessageException.class)
public void testGetMessageThrowsException() {
CompositeMessageSource compositeMessageSource = new CompositeMessageSource();

compositeMessageSource.getMessage(
"message.not.found",
new Object[]{"arg1"},
Locale.ENGLISH
);
}

@Test
public void testGetMessageWithResolvable() {
CompositeMessageSource compositeMessageSource = new CompositeMessageSource();

StaticMessageSource staticMessageSource = new StaticMessageSource();
staticMessageSource.addMessage("message.resolvable", Locale.ENGLISH, "Resolvable: {0}");

compositeMessageSource.addMessageSource(staticMessageSource);

MessageSourceResolvable resolvable = new MessageSourceResolvable() {
@Override
public String[] getCodes() {
return new String[]{"message.resolvable"};
}

@Override
public Object[] getArguments() {
return new Object[]{"test-arg"};
}

@Override
public String getDefaultMessage() {
return "default";
}
};

String result = compositeMessageSource.getMessage(resolvable, Locale.ENGLISH);
assertEquals("Resolvable: test-arg", result);
}

@Test
public void testMultipleMessageSources() {
CompositeMessageSource compositeMessageSource = new CompositeMessageSource();

StaticMessageSource source1 = new StaticMessageSource();
source1.addMessage("message.first", Locale.ENGLISH, "First: {0}");

StaticMessageSource source2 = new StaticMessageSource();
source2.addMessage("message.second", Locale.ENGLISH, "Second: {0}");

compositeMessageSource.addMessageSource(source1);
compositeMessageSource.addMessageSource(source2);

// 测试第一个消息源
String result1 = compositeMessageSource.getMessage(
"message.first",
new Object[]{"value1"},
null,
Locale.ENGLISH
);
assertEquals("First: value1", result1);

// 测试第二个消息源
String result2 = compositeMessageSource.getMessage(
"message.second",
new Object[]{"value2"},
null,
Locale.ENGLISH
);
assertEquals("Second: value2", result2);
}

@Test
public void testModbusScenario() {
// 模拟实际的 Modbus 场景
CompositeMessageSource compositeMessageSource = new CompositeMessageSource();

StaticMessageSource staticMessageSource = new StaticMessageSource();
staticMessageSource.addMessage(
"message.modbus.send_failed",
Locale.ENGLISH,
"Modbus message send failed, device: {0}, error: {1}"
);

compositeMessageSource.addMessageSource(staticMessageSource);

String result = compositeMessageSource.getMessage(
"message.modbus.send_failed",
new Object[]{"device-123", "Connection refused"},
"Modbus 消息发送失败, 设备: {0}, 错误: {1}",
Locale.ENGLISH
);

assertEquals("Modbus message send failed, device: device-123, error: Connection refused", result);
}

@Test
public void testNullDefaultMessage() {
CompositeMessageSource compositeMessageSource = new CompositeMessageSource();

String result = compositeMessageSource.getMessage(
"message.not.found",
new Object[]{"arg1"},
null,
Locale.ENGLISH
);

assertNull(result);
}
}