diff --git a/java/com/google/gerrit/server/args4j/AccountGroupIdHandler.java b/java/com/google/gerrit/server/args4j/AccountGroupIdHandler.java index f3393c1db7..46a22c06ed 100644 --- a/java/com/google/gerrit/server/args4j/AccountGroupIdHandler.java +++ b/java/com/google/gerrit/server/args4j/AccountGroupIdHandler.java @@ -14,6 +14,8 @@ package com.google.gerrit.server.args4j; +import static com.google.gerrit.util.cli.Localizable.localizable; + import com.google.gerrit.reviewdb.client.AccountGroup; import com.google.gerrit.server.account.GroupCache; import com.google.gerrit.server.group.InternalGroup; @@ -45,7 +47,7 @@ public class AccountGroupIdHandler extends OptionHandler { final String n = params.getParameter(0); Optional group = groupCache.get(new AccountGroup.NameKey(n)); if (!group.isPresent()) { - throw new CmdLineException(owner, "Group \"" + n + "\" does not exist"); + throw new CmdLineException(owner, localizable("Group \"%s\" does not exist"), n); } setter.addValue(group.get().getId()); return 1; diff --git a/java/com/google/gerrit/server/args4j/AccountGroupUUIDHandler.java b/java/com/google/gerrit/server/args4j/AccountGroupUUIDHandler.java index 4d589a038b..2dd0c7ab5b 100644 --- a/java/com/google/gerrit/server/args4j/AccountGroupUUIDHandler.java +++ b/java/com/google/gerrit/server/args4j/AccountGroupUUIDHandler.java @@ -14,6 +14,8 @@ package com.google.gerrit.server.args4j; +import static com.google.gerrit.util.cli.Localizable.localizable; + import com.google.gerrit.common.data.GroupDescription; import com.google.gerrit.common.data.GroupReference; import com.google.gerrit.reviewdb.client.AccountGroup; @@ -77,7 +79,7 @@ public class AccountGroupUUIDHandler extends OptionHandler { GroupReference group = GroupBackends.findExactSuggestion(groupBackend, n); if (group == null) { - throw new CmdLineException(owner, "Group \"" + n + "\" does not exist"); + throw new CmdLineException(owner, localizable("Group \"%s\" does not exist"), n); } setter.addValue(group.getUUID()); return 1; diff --git a/java/com/google/gerrit/server/args4j/AccountIdHandler.java b/java/com/google/gerrit/server/args4j/AccountIdHandler.java index c7d3f73b68..2b66334f74 100644 --- a/java/com/google/gerrit/server/args4j/AccountIdHandler.java +++ b/java/com/google/gerrit/server/args4j/AccountIdHandler.java @@ -14,6 +14,8 @@ package com.google.gerrit.server.args4j; +import static com.google.gerrit.util.cli.Localizable.localizable; + import com.google.gerrit.extensions.client.AuthType; import com.google.gerrit.reviewdb.client.Account; import com.google.gerrit.server.account.AccountException; @@ -76,11 +78,11 @@ public class AccountIdHandler extends OptionHandler { case OPENID: case OPENID_SSO: default: - throw new CmdLineException(owner, "user \"" + token + "\" not found"); + throw new CmdLineException(owner, localizable("user \"%s\" not found"), token); } } } catch (OrmException e) { - throw new CmdLineException(owner, "database is down"); + throw new CmdLineException(owner, localizable("database is down")); } catch (IOException e) { throw new CmdLineException(owner, "Failed to load account", e); } catch (ConfigInvalidException e) { @@ -92,7 +94,7 @@ public class AccountIdHandler extends OptionHandler { private Account.Id createAccountByLdap(String user) throws CmdLineException, IOException { if (!ExternalId.isValidUsername(user)) { - throw new CmdLineException(owner, "user \"" + user + "\" not found"); + throw new CmdLineException(owner, localizable("user \"%s\" not found"), user); } try { @@ -100,7 +102,7 @@ public class AccountIdHandler extends OptionHandler { req.setSkipAuthentication(true); return accountManager.authenticate(req).getAccountId(); } catch (AccountException e) { - throw new CmdLineException(owner, "user \"" + user + "\" not found"); + throw new CmdLineException(owner, localizable("user \"%s\" not found"), user); } } diff --git a/java/com/google/gerrit/server/args4j/ChangeIdHandler.java b/java/com/google/gerrit/server/args4j/ChangeIdHandler.java index adb5f63547..13832fabb0 100644 --- a/java/com/google/gerrit/server/args4j/ChangeIdHandler.java +++ b/java/com/google/gerrit/server/args4j/ChangeIdHandler.java @@ -14,6 +14,8 @@ package com.google.gerrit.server.args4j; +import static com.google.gerrit.util.cli.Localizable.localizable; + import com.google.common.base.Splitter; import com.google.gerrit.reviewdb.client.Branch; import com.google.gerrit.reviewdb.client.Change; @@ -52,7 +54,7 @@ public class ChangeIdHandler extends OptionHandler { final List tokens = Splitter.on(',').splitToList(token); if (tokens.size() != 3) { throw new CmdLineException( - owner, "change should be specified as ,,"); + owner, localizable("change should be specified as ,,")); } try { @@ -64,12 +66,12 @@ public class ChangeIdHandler extends OptionHandler { return 1; } } catch (IllegalArgumentException e) { - throw new CmdLineException(owner, "Change-Id is not valid"); + throw new CmdLineException(owner, localizable("Change-Id is not valid")); } catch (OrmException e) { - throw new CmdLineException(owner, "Database error: " + e.getMessage()); + throw new CmdLineException(owner, localizable("Database error: %s"), e.getMessage()); } - throw new CmdLineException(owner, "\"" + token + "\": change not found"); + throw new CmdLineException(owner, localizable("\"%s\": change not found"), token); } @Override diff --git a/java/com/google/gerrit/server/args4j/PatchSetIdHandler.java b/java/com/google/gerrit/server/args4j/PatchSetIdHandler.java index cb70abfe4c..84c1d88d2a 100644 --- a/java/com/google/gerrit/server/args4j/PatchSetIdHandler.java +++ b/java/com/google/gerrit/server/args4j/PatchSetIdHandler.java @@ -14,6 +14,8 @@ package com.google.gerrit.server.args4j; +import static com.google.gerrit.util.cli.Localizable.localizable; + import com.google.gerrit.reviewdb.client.PatchSet; import com.google.inject.Inject; import com.google.inject.assistedinject.Assisted; @@ -41,7 +43,7 @@ public class PatchSetIdHandler extends OptionHandler { try { id = PatchSet.Id.parse(token); } catch (IllegalArgumentException e) { - throw new CmdLineException(owner, "\"" + token + "\" is not a valid patch set"); + throw new CmdLineException(owner, localizable("\"%s\" is not a valid patch set"), token); } setter.addValue(id); diff --git a/java/com/google/gerrit/server/args4j/ProjectHandler.java b/java/com/google/gerrit/server/args4j/ProjectHandler.java index 7872812b6c..223b112563 100644 --- a/java/com/google/gerrit/server/args4j/ProjectHandler.java +++ b/java/com/google/gerrit/server/args4j/ProjectHandler.java @@ -14,6 +14,8 @@ package com.google.gerrit.server.args4j; +import static com.google.gerrit.util.cli.Localizable.localizable; + import com.google.common.flogger.FluentLogger; import com.google.gerrit.common.ProjectUtil; import com.google.gerrit.extensions.restapi.AuthException; @@ -76,7 +78,7 @@ public class ProjectHandler extends OptionHandler { try { state = projectCache.checkedGet(nameKey); if (state == null) { - throw new CmdLineException(owner, String.format("project %s not found", nameWithoutSuffix)); + throw new CmdLineException(owner, localizable("project %s not found"), nameWithoutSuffix); } // Hidden projects(permitsRead = false) should only be accessible by the project owners. // READ_CONFIG is checked here because it's only allowed to project owners(ACCESS may also @@ -86,10 +88,12 @@ public class ProjectHandler extends OptionHandler { state.statePermitsRead() ? ProjectPermission.ACCESS : ProjectPermission.READ_CONFIG; permissionBackend.currentUser().project(nameKey).check(permissionToCheck); } catch (AuthException e) { - throw new CmdLineException(owner, new NoSuchProjectException(nameKey).getMessage()); + throw new CmdLineException( + owner, localizable(new NoSuchProjectException(nameKey).getMessage())); } catch (PermissionBackendException | IOException e) { logger.atWarning().withCause(e).log("Cannot load project %s", nameWithoutSuffix); - throw new CmdLineException(owner, new NoSuchProjectException(nameKey).getMessage()); + throw new CmdLineException( + owner, localizable(new NoSuchProjectException(nameKey).getMessage())); } setter.addValue(state); diff --git a/java/com/google/gerrit/server/args4j/SocketAddressHandler.java b/java/com/google/gerrit/server/args4j/SocketAddressHandler.java index 4325c002cc..198cf6722e 100644 --- a/java/com/google/gerrit/server/args4j/SocketAddressHandler.java +++ b/java/com/google/gerrit/server/args4j/SocketAddressHandler.java @@ -14,6 +14,8 @@ package com.google.gerrit.server.args4j; +import static com.google.gerrit.util.cli.Localizable.localizable; + import com.google.gerrit.server.util.SocketUtil; import com.google.inject.Inject; import com.google.inject.assistedinject.Assisted; @@ -41,7 +43,7 @@ public class SocketAddressHandler extends OptionHandler { try { setter.addValue(SocketUtil.parse(token, 0)); } catch (IllegalArgumentException e) { - throw new CmdLineException(owner, e.getMessage()); + throw new CmdLineException(owner, localizable(e.getMessage())); } return 1; } diff --git a/java/com/google/gerrit/server/restapi/BUILD b/java/com/google/gerrit/server/restapi/BUILD index 1207c71136..251c7c13c8 100644 --- a/java/com/google/gerrit/server/restapi/BUILD +++ b/java/com/google/gerrit/server/restapi/BUILD @@ -18,6 +18,7 @@ java_library( "//java/com/google/gerrit/reviewdb:server", "//java/com/google/gerrit/server", "//java/com/google/gerrit/server/ioutil", + "//java/com/google/gerrit/util/cli", "//java/org/eclipse/jgit:server", "//lib:args4j", "//lib:blame-cache", diff --git a/java/com/google/gerrit/server/restapi/change/GetDiff.java b/java/com/google/gerrit/server/restapi/change/GetDiff.java index 489c7cbb1e..1fae7391ae 100644 --- a/java/com/google/gerrit/server/restapi/change/GetDiff.java +++ b/java/com/google/gerrit/server/restapi/change/GetDiff.java @@ -15,6 +15,7 @@ package com.google.gerrit.server.restapi.change; import static com.google.common.base.Preconditions.checkState; +import static com.google.gerrit.util.cli.Localizable.localizable; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; @@ -440,9 +441,9 @@ public class GetDiff implements RestReadView { } catch (NumberFormatException e) { throw new CmdLineException( owner, - String.format( - "\"%s\" is not a valid value for \"%s\"", - value, ((NamedOptionDef) option).name())); + localizable("\"%s\" is not a valid value for \"%s\""), + value, + ((NamedOptionDef) option).name()); } } setter.addValue(context); diff --git a/java/com/google/gerrit/sshd/commands/ApproveOption.java b/java/com/google/gerrit/sshd/commands/ApproveOption.java index f65f77c8c8..cda340de51 100644 --- a/java/com/google/gerrit/sshd/commands/ApproveOption.java +++ b/java/com/google/gerrit/sshd/commands/ApproveOption.java @@ -14,6 +14,8 @@ package com.google.gerrit.sshd.commands; +import static com.google.gerrit.util.cli.Localizable.localizable; + import com.google.gerrit.common.data.LabelType; import com.google.gerrit.common.data.LabelValue; import java.lang.annotation.Annotation; @@ -160,7 +162,7 @@ final class ApproveOption implements Option, Setter { + " for \"" + name + "\""; - throw new CmdLineException(owner, e); + throw new CmdLineException(owner, localizable(e)); } return value; } diff --git a/java/com/google/gerrit/util/cli/CmdLineParser.java b/java/com/google/gerrit/util/cli/CmdLineParser.java index dc998c3ac9..8639a0688c 100644 --- a/java/com/google/gerrit/util/cli/CmdLineParser.java +++ b/java/com/google/gerrit/util/cli/CmdLineParser.java @@ -34,6 +34,8 @@ package com.google.gerrit.util.cli; +import static com.google.gerrit.util.cli.Localizable.localizable; + import com.google.common.base.Strings; import com.google.common.collect.ListMultimap; import com.google.common.collect.Lists; @@ -320,7 +322,7 @@ public class CmdLineParser { return false; } - throw new CmdLineException(parser, String.format("invalid boolean \"%s=%s\"", name, value)); + throw new CmdLineException(parser, localizable("invalid boolean \"%s=%s\""), name, value); } private static class PrefixedOption implements Option { @@ -586,6 +588,6 @@ public class CmdLineParser { } public CmdLineException reject(String message) { - return new CmdLineException(parser, message); + return new CmdLineException(parser, localizable(message)); } } diff --git a/java/com/google/gerrit/util/cli/Localizable.java b/java/com/google/gerrit/util/cli/Localizable.java new file mode 100644 index 0000000000..33989d316a --- /dev/null +++ b/java/com/google/gerrit/util/cli/Localizable.java @@ -0,0 +1,39 @@ +// Copyright (C) 2018 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.util.cli; + +import java.util.Locale; + +public class Localizable implements org.kohsuke.args4j.Localizable { + private final String format; + + @Override + public String formatWithLocale(Locale locale, Object... args) { + return String.format(locale, format, args); + } + + @Override + public String format(Object... args) { + return String.format(format, args); + } + + private Localizable(String format) { + this.format = format; + } + + public static Localizable localizable(String format) { + return new Localizable(format); + } +}