Như NilsH gợi ý MessageFormat là thật sự tốt đẹp cho mục đích này. Để có các biến tên bạn có thể ẩn đằng sau MessageFormat lớp học của bạn:
public class FormattedStrSubstitutor {
public static String formatReplace(Object source, Map<String, String> valueMap) {
for (Map.Entry<String, String> entry : valueMap.entrySet()) {
String val = entry.getValue();
if (isPlaceholder(val)) {
val = getPlaceholderValue(val);
String newValue = reformat(val);
entry.setValue(newValue);
}
}
return new StrSubstitutor(valueMap).replace(source);
}
private static boolean isPlaceholder(String isPlaceholder) {
return isPlaceholder.startsWith("${");
}
private static String getPlaceholderValue(String val) {
return val.substring(2, val.length()-1);
}
private static String reformat(String format) {
String result = MessageFormat.format("{0,date," + format + "}", new Date());
return result;
}
}
Và bạn phải điều chỉnh testcase của bạn:
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
String template = ".../uploads/${customer}/${dateTime}/report.pdf";
@Test
public void shouldResolvePlaceholder() {
final Map<String, String> model = new HashMap<String, String>();
model.put("customer", "Mr. Foobar");
model.put("dateTime", "${yyyyMMdd}");
final String filledTemplate = FormattedStrSubstitutor.formatReplace(this.template,
model);
assertEquals(".../uploads/Mr. Foobar/" + this.formatter.format(new Date())
+ "/report.pdf", filledTemplate);
}
Tôi đã gỡ bỏ Generics và thay thế những với String. Ngoài ra, isPlaceholder
và getPlaceholderValue
được mã hóa cứng và mong đợi cú pháp $ {value}.
Nhưng đây chỉ là ý tưởng để giải quyết vấn đề của bạn. Để thực hiện việc này, bạn có thể sử dụng các phương thức từ StrSubstitutor
(chỉ cần sử dụng hoặc thực hiện FormattedStrSubstitutor extends StrSubstitutor
).
Ngoài ra, bạn có thể sử dụng ví dụ $ d {value} để định dạng ngày và $ foo {value} để định dạng foo.
CẬP NHẬT
Không thể ngủ mà không có giải pháp đầy đủ. Bạn có thể thêm phương pháp này để FormattedStrSubstitutor
lớp:
public static String replace(Object source,
Map<String, String> valueMap) {
String staticResolved = new StrSubstitutor(valueMap).replace(source);
Pattern p = Pattern.compile("(\\$\\{date)(.*?)(\\})");
Matcher m = p.matcher(staticResolved);
String dynamicResolved = staticResolved;
while (m.find()) {
String result = MessageFormat.format("{0,date" + m.group(2) + "}",
new Date());
dynamicResolved = dynamicResolved.replace(m.group(), result);
}
return dynamicResolved;
}
testcase của bạn giống như trong câu hỏi của bạn (thay đổi nhỏ trong placeholder):
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
String template = ".../uploads/${customer}/${date,yyyyMMdd}/report.pdf";
@Test
public void shouldResolvePlaceholder() {
final Map<String, String> model = new HashMap<String, String>();
model.put("customer", "Mr. Foobar");
final String filledTemplate = FormattedStrSubstitutor.replace(this.template,
model);
assertEquals(
".../uploads/Mr. Foobar/" + this.formatter.format(new Date())
+ "/report.pdf", filledTemplate);
}
Cùng hạn chế như trước đây; không có generics và sửa tiền tố và hậu tố cho trình giữ chỗ.
là phần ngày luôn là thư mục cuối cùng trong cấu trúc thư mục của bạn? –
Không, trong một số báo cáo khác là ở giữa. Hoặc trong tên tệp. Đây chỉ là một ví dụ. – d0x