private void assertArgsHaveBundle(ResourceBundle orig, List<? extends ArgSpec> args) { assertFalse("args should not be empty", args.isEmpty()); for (ArgSpec arg : args) { assertNotNull("Messages for " + arg.toString(), arg.messages()); assertSame(arg.toString(), orig, arg.messages().resourceBundle()); } }
/** 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. * @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, * and if not found, it will try with the unqualified key. * @param defaultValues value to return if the resource bundle is null or empty, or if no value was found by the qualified or unqualified key * @return the String array value found in the resource bundle for the specified key, or the specified default value */ 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]); } private static List<String> addAllWithPrefix(ResourceBundle rb, String key, Set<String> keys, List<String> result) {
void updateFromCommand(Command cmd, CommandSpec commandSpec) { if (isNonDefault(cmd.synopsisHeading(), DEFAULT_SYNOPSIS_HEADING)) {synopsisHeading = cmd.synopsisHeading();} if (isNonDefault(cmd.commandListHeading(), DEFAULT_COMMAND_LIST_HEADING)) {commandListHeading = cmd.commandListHeading();} if (isNonDefault(cmd.requiredOptionMarker(), DEFAULT_REQUIRED_OPTION_MARKER)) {requiredOptionMarker = cmd.requiredOptionMarker();} if (isNonDefault(cmd.abbreviateSynopsis(), DEFAULT_ABBREVIATE_SYNOPSIS)) {abbreviateSynopsis = cmd.abbreviateSynopsis();} if (isNonDefault(cmd.sortOptions(), DEFAULT_SORT_OPTIONS)) {sortOptions = cmd.sortOptions();} if (isNonDefault(cmd.showDefaultValues(), DEFAULT_SHOW_DEFAULT_VALUES)) {showDefaultValues = cmd.showDefaultValues();} if (isNonDefault(cmd.hidden(), DEFAULT_HIDDEN)) {hidden = cmd.hidden();} if (isNonDefault(cmd.customSynopsis(), DEFAULT_MULTI_LINE)) {customSynopsis = cmd.customSynopsis().clone();} if (isNonDefault(cmd.description(), DEFAULT_MULTI_LINE)) {description = cmd.description().clone();} if (isNonDefault(cmd.descriptionHeading(), DEFAULT_SINGLE_VALUE)) {descriptionHeading = cmd.descriptionHeading();} if (isNonDefault(cmd.header(), DEFAULT_MULTI_LINE)) {header = cmd.header().clone();} if (isNonDefault(cmd.headerHeading(), DEFAULT_SINGLE_VALUE)) {headerHeading = cmd.headerHeading();} if (isNonDefault(cmd.footer(), DEFAULT_MULTI_LINE)) {footer = cmd.footer().clone();} if (isNonDefault(cmd.footerHeading(), DEFAULT_SINGLE_VALUE)) {footerHeading = cmd.footerHeading();} if (isNonDefault(cmd.parameterListHeading(), DEFAULT_SINGLE_VALUE)) {parameterListHeading = cmd.parameterListHeading();} if (isNonDefault(cmd.optionListHeading(), DEFAULT_SINGLE_VALUE)) {optionListHeading = cmd.optionListHeading();} if (isNonDefault(cmd.usageHelpWidth(), DEFAULT_USAGE_WIDTH)) {width(cmd.usageHelpWidth());} // validate ResourceBundle rb = empty(cmd.resourceBundle()) ? null : ResourceBundle.getBundle(cmd.resourceBundle()); if (rb != null) { messages(new Messages(commandSpec, rb)); } // else preserve superclass bundle } void initFromMixin(UsageMessageSpec mixin, CommandSpec commandSpec) {
void initFrom(UsageMessageSpec settings, CommandSpec commandSpec) { description = settings.description; customSynopsis = settings.customSynopsis; header = settings.header; footer = settings.footer; abbreviateSynopsis = settings.abbreviateSynopsis; sortOptions = settings.sortOptions; showDefaultValues = settings.showDefaultValues; hidden = settings.hidden; requiredOptionMarker = settings.requiredOptionMarker; headerHeading = settings.headerHeading; synopsisHeading = settings.synopsisHeading; descriptionHeading = settings.descriptionHeading; parameterListHeading = settings.parameterListHeading; optionListHeading = settings.optionListHeading; commandListHeading = settings.commandListHeading; footerHeading = settings.footerHeading; width = settings.width; messages = Messages.copy(commandSpec, settings.messages()); } }
void initFromMixin(UsageMessageSpec mixin, CommandSpec commandSpec) { if (initializable(synopsisHeading, mixin.synopsisHeading(), DEFAULT_SYNOPSIS_HEADING)) {synopsisHeading = mixin.synopsisHeading();} if (initializable(commandListHeading, mixin.commandListHeading(), DEFAULT_COMMAND_LIST_HEADING)) {commandListHeading = mixin.commandListHeading();} if (initializable(requiredOptionMarker, mixin.requiredOptionMarker(), DEFAULT_REQUIRED_OPTION_MARKER)) {requiredOptionMarker = mixin.requiredOptionMarker();} if (initializable(abbreviateSynopsis, mixin.abbreviateSynopsis(), DEFAULT_ABBREVIATE_SYNOPSIS)) {abbreviateSynopsis = mixin.abbreviateSynopsis();} if (initializable(sortOptions, mixin.sortOptions(), DEFAULT_SORT_OPTIONS)) {sortOptions = mixin.sortOptions();} if (initializable(showDefaultValues, mixin.showDefaultValues(), DEFAULT_SHOW_DEFAULT_VALUES)) {showDefaultValues = mixin.showDefaultValues();} if (initializable(hidden, mixin.hidden(), DEFAULT_HIDDEN)) {hidden = mixin.hidden();} if (initializable(customSynopsis, mixin.customSynopsis(), DEFAULT_MULTI_LINE)) {customSynopsis = mixin.customSynopsis().clone();} if (initializable(description, mixin.description(), DEFAULT_MULTI_LINE)) {description = mixin.description().clone();} if (initializable(descriptionHeading, mixin.descriptionHeading(), DEFAULT_SINGLE_VALUE)) {descriptionHeading = mixin.descriptionHeading();} if (initializable(header, mixin.header(), DEFAULT_MULTI_LINE)) {header = mixin.header().clone();} if (initializable(headerHeading, mixin.headerHeading(), DEFAULT_SINGLE_VALUE)) {headerHeading = mixin.headerHeading();} if (initializable(footer, mixin.footer(), DEFAULT_MULTI_LINE)) {footer = mixin.footer().clone();} if (initializable(footerHeading, mixin.footerHeading(), DEFAULT_SINGLE_VALUE)) {footerHeading = mixin.footerHeading();} if (initializable(parameterListHeading, mixin.parameterListHeading(), DEFAULT_SINGLE_VALUE)) {parameterListHeading = mixin.parameterListHeading();} if (initializable(optionListHeading, mixin.optionListHeading(), DEFAULT_SINGLE_VALUE)) {optionListHeading = mixin.optionListHeading();} if (Messages.empty(messages)) { messages(Messages.copy(commandSpec, mixin.messages())); } } void initFrom(UsageMessageSpec settings, CommandSpec commandSpec) {
/** Returns the description template of this option, before variables are {@linkplain Option#description() rendered}. * If a resource bundle has been {@linkplain ArgSpec#messages(Messages) set}, this method will first try to find a value in the resource bundle: * If the resource bundle has no entry for the {@code fully qualified commandName + "." + descriptionKey} or for the unqualified {@code descriptionKey}, * an attempt is made to find the option description using any of the option names (without leading hyphens) as key, * first with the {@code fully qualified commandName + "."} prefix, then without. * @see CommandSpec#qualifiedName(String) * @see Option#description() */ @Override public String[] description() { if (messages() == null) { return super.description(); } String[] newValue = messages().getStringArray(descriptionKey(), null); if (newValue != null) { return newValue; } for (String name : names()) { newValue = messages().getStringArray(CommandSpec.stripPrefix(name), null); if (newValue != null) { return newValue; } } return super.description(); }
/** Returns the description template of this positional parameter, before variables are {@linkplain Parameters#description() rendered}. * If a resource bundle has been {@linkplain ArgSpec#messages(Messages) set}, this method will first try to find a value in the resource bundle: * If the resource bundle has no entry for the {@code fully qualified commandName + "." + descriptionKey} or for the unqualified {@code descriptionKey}, * an attempt is made to find the positional parameter description using {@code paramLabel() + "[" + index() + "]"} as key, * first with the {@code fully qualified commandName + "."} prefix, then without. * @see Parameters#description() * @see CommandSpec#qualifiedName(String) * @since 3.6 */ @Override public String[] description() { if (messages() == null) { return super.description(); } String[] newValue = messages().getStringArray(descriptionKey(), null); if (newValue != null) { return newValue; } newValue = messages().getStringArray(paramLabel() + "[" + index() + "]", null); if (newValue != null) { return newValue; } return super.description(); }
/** 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. * @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, * and if not found, it will try with the unqualified key. * @param defaultValues value to return if the resource bundle is null or empty, or if no value was found by the qualified or unqualified key * @return the String array value found in the resource bundle for the specified key, or the specified default value */ 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]); } private static List<String> addAllWithPrefix(ResourceBundle rb, String key, Set<String> keys, List<String> result) {
private String resourceStr(String key) { return messages == null ? null : messages.getString(key, null); } private String[] resourceArr(String key) { return messages == null ? null : messages.getStringArray(key, null); }
private String[] resourceArr(String key) { return messages == null ? null : messages.getStringArray(key, null); }
/** Returns the ResourceBundle of the specified Messages object or {@code null} if the specified Messages object is {@code null}. */ public static ResourceBundle resourceBundle(Messages messages) { return messages == null ? null : messages.resourceBundle(); } /** Returns the ResourceBundle of this object or {@code null}. */
@Test public void testMessagesCopyNull() { assertNull(Messages.copy(CommandSpec.create(), null)); }
/** 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, * and if not found, it will try with the unqualified key. * @param defaultValue value to return if the resource bundle is null or empty, or if no value was found by the qualified or unqualified key * @return the String value found in the resource bundle for the specified key, or the specified default value */ 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; }
/** Initializes the resource bundle for this command: sets the {@link UsageMessageSpec#messages(Messages) UsageMessageSpec.messages} to * a {@link Messages Messages} object created from this command spec and the specified bundle, and then sets the * {@link ArgSpec#messages(Messages) ArgSpec.messages} of all options and positional parameters in this command * to the same {@code Messages} instance. Subcommands are not modified. * @param bundle the ResourceBundle to set, may be {@code null} * @return this commandSpec * @see #addSubcommand(String, CommandLine) * @since 3.6 */ public CommandSpec resourceBundle(ResourceBundle bundle) { usageMessage().messages(new Messages(this, bundle)); updateArgSpecMessages(); return this; } private void updateArgSpecMessages() {
@Test public void testMessagesGetStringArrayNullKey() { String[] def = {"abc"}; assertSame(def, new Messages(CommandSpec.create(), null).getStringArray(null, def)); assertSame(def, new Messages(CommandSpec.create(), null).getStringArray("help", def)); ResourceBundle rb = ResourceBundle.getBundle("picocli.SharedMessages"); assertSame(def, new Messages(CommandSpec.create(), rb).getStringArray(null, def)); assertNotEquals(def, new Messages(CommandSpec.create(), rb).getStringArray("usage.description", def)); } }
@Test public void testMessagesGetStringNullKey() { String def = "abc"; assertSame(def, new Messages(CommandSpec.create(), null).getString(null, def)); assertSame(def, new Messages(CommandSpec.create(), null).getString("help", def)); ResourceBundle rb = ResourceBundle.getBundle("picocli.SharedMessages"); assertSame(def, new Messages(CommandSpec.create(), rb).getString(null, def)); assertNotEquals(def, new Messages(CommandSpec.create(), rb).getString("help", def)); }
/** Returns a copy of the specified Messages object with the CommandSpec replaced by the specified one. * @param spec the CommandSpec of the returned Messages * @param original the Messages object whose ResourceBundle to reference * @return a Messages object with the specified CommandSpec and the ResourceBundle of the specified Messages object */ public static Messages copy(CommandSpec spec, Messages original) { return original == null ? null : new Messages(spec, original.rb); } /** Returns {@code true} if the specified {@code Messages} is {@code null} or has a {@code null ResourceBundle}. */
private void assertArgsHaveBundle(ResourceBundle orig, List<? extends ArgSpec> args) { assertFalse("args should not be empty", args.isEmpty()); for (ArgSpec arg : args) { assertNotNull("Messages for " + arg.toString(), arg.messages()); assertSame(arg.toString(), orig, arg.messages().resourceBundle()); } }
/** Returns the resource bundle for this command. * @return the resource bundle from the {@linkplain UsageMessageSpec#messages()} * @since 3.6 */ public ResourceBundle resourceBundle() { return Messages.resourceBundle(usageMessage.messages()); } /** Initializes the resource bundle for this command: sets the {@link UsageMessageSpec#messages(Messages) UsageMessageSpec.messages} to
@Test public void testMessagesCommandSpec() { CommandSpec spec = CommandSpec.create(); Messages orig = new Messages(spec, null); assertSame(spec, orig.commandSpec()); }