Skip to content

Commit

Permalink
[remkop#1706] Resolve messages against parent resource bundles
Browse files Browse the repository at this point in the history
  • Loading branch information
rsenden committed Jun 13, 2022
1 parent 288337b commit 6530068
Showing 1 changed file with 39 additions and 10 deletions.
49 changes: 39 additions & 10 deletions src/main/java/picocli/CommandLine.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import picocli.CommandLine.Help.Ansi.IStyle;
import picocli.CommandLine.Help.Ansi.Style;
import picocli.CommandLine.Help.Ansi.Text;
Expand Down Expand Up @@ -11558,6 +11559,7 @@ public static class Messages {
private final String bundleBaseName;
private final ResourceBundle rb;
private final Set<String> keys;
private Messages parent;
public Messages(CommandSpec spec, String baseName) {
this(spec, baseName, createBundle(baseName));
}
Expand All @@ -11581,6 +11583,21 @@ private static String extractName(ResourceBundle rb) {
return (String) ResourceBundle.class.getDeclaredMethod("getBaseBundleName").invoke(rb);
} catch (Exception ignored) { return "?"; }
}
public Messages parent() {
CommandSpec parentSpec = this.spec.parent();
if ( parent==null || parent.spec!=parentSpec ) {
parent = null; // Refresh if parentSpec doesn't match
while ( parent==null && parentSpec!=null ) {
String parentResourceBundleBaseName = parentSpec.resourceBundleBaseName();
if ( parentResourceBundleBaseName!=null && !parentResourceBundleBaseName.equals(this.bundleBaseName)) {
parent = new Messages(parentSpec, parentResourceBundleBaseName);
} else {
parentSpec = parentSpec.parent();
}
}
}
return parent;
}
private static Set<String> keys(ResourceBundle rb) {
if (rb == null) { return Collections.emptySet(); }
Set<String> keys = new LinkedHashSet<String>();
Expand All @@ -11596,8 +11613,8 @@ private static Set<String> keys(ResourceBundle rb) {
public static Messages copy(CommandSpec spec, Messages original) {
return original == null ? null : new Messages(spec, original.bundleBaseName, original.rb);
}
/** Returns {@code true} if the specified {@code Messages} is {@code null} or has a {@code null ResourceBundle}. */
public static boolean empty(Messages messages) { return messages == null || messages.rb == null; }
/** Returns {@code true} if the specified {@code Messages} is {@code null}, has a {@code null ResourceBundle}, or has a {@code null parent Messages}. */
public static boolean empty(Messages messages) { return messages == null || messages.isEmpty(); }

/** Returns the String value found in the resource bundle for the specified key, or the specified default value if not found.
* @param key unqualified resource bundle key. This method will first try to find a value by qualifying the key with the command's fully qualified name,
Expand All @@ -11608,12 +11625,19 @@ public static Messages copy(CommandSpec spec, Messages original) {
public String getString(String key, String defaultValue) {
if (isEmpty()) { return defaultValue; }
String cmd = spec.qualifiedName(".");
if (keys.contains(cmd + "." + key)) { return rb.getString(cmd + "." + key); }
if (keys.contains(key)) { return rb.getString(key); }
return defaultValue;
String qualifiedKey = cmd + "." + key;
String result = getStringForExactKey(qualifiedKey);
if ( result==null ) { result = getStringForExactKey(key); }
return result!=null ? result : defaultValue;
}

private String getStringForExactKey(String key) {
if (keys.contains(key)) { return rb.getString(key); }
else if (parent()!=null) { return parent().getStringForExactKey(key); }
else { return null; }
}

boolean isEmpty() { return rb == null || keys.isEmpty(); }
boolean isEmpty() { return (rb == null || keys.isEmpty()) && (parent()==null || parent().isEmpty()); }

/** Returns the String array value found in the resource bundle for the specified key, or the specified default value if not found.
* Multi-line strings can be specified in the resource bundle with {@code key.0}, {@code key.1}, {@code key.2}, etc.
Expand All @@ -11625,10 +11649,15 @@ public String getString(String key, String defaultValue) {
public String[] getStringArray(String key, String[] defaultValues) {
if (isEmpty()) { return defaultValues; }
String cmd = spec.qualifiedName(".");
List<String> result = addAllWithPrefix(rb, cmd + "." + key, keys, new ArrayList<String>());
if (!result.isEmpty()) { return result.toArray(new String[0]); }
addAllWithPrefix(rb, key, keys, result);
return result.isEmpty() ? defaultValues : result.toArray(new String[0]);
String qualifiedKey = cmd + "." + key;
String[] result = getStringArrayForExactKey(qualifiedKey);
if ( result==null ) { result = getStringArrayForExactKey(key); }
return result!=null ? result : defaultValues;
}
private String[] getStringArrayForExactKey(String key) {
List<String> result = addAllWithPrefix(rb, key, keys, new ArrayList<String>());
if (!result.isEmpty()) { return result.toArray(new String[0]); }
return parent()==null ? null : parent().getStringArrayForExactKey(key);
}
private static List<String> addAllWithPrefix(ResourceBundle rb, String key, Set<String> keys, List<String> result) {
if (keys.contains(key)) { result.add(rb.getString(key)); }
Expand Down

0 comments on commit 6530068

Please sign in to comment.