Pergunta

Tínhamos muitas cordas que continham a mesma sub-string, de frases sobre a verificação do log ou como entrar em contato com o suporte, a seqüências de marcas que contêm a empresa ou o nome do produto. A repetição estava causando alguns problemas para nós mesmos (principalmente erros de digitação ou copiar/colar), mas também causa problemas, pois aumenta a quantidade de texto que nosso tradutor deve traduzir.

A solução que eu criei foi algo assim:

public class ExpandingResourceBundleControl extends ResourceBundle.Control {
  public static final ResourceBundle.Control EXPANDING =
    new ExpandingResourceBundleControl();

  private ExpandingResourceBundleControl() { }

  @Override
  public ResourceBundle newBundle(String baseName, Locale locale, String format,
                                  ClassLoader loader, boolean reload)
    throws IllegalAccessException, InstantiationException, IOException {

      ResourceBundle inner = super.newBundle(baseName, locale, format, loader, reload);
      return inner == null ? null : new ExpandingResourceBundle(inner, loader);
  }
}

ExpandingResourceBundle Delegados no pacote de recursos reais, mas executa a conversão de {{this.kind.of.thing}} para procurar a chave nos recursos.

Toda vez que você deseja obter um desses, você tem que ir:

ResourceBundle.getBundle("com/acme/app/Bundle", EXPANDING);

E isso funciona bem - por um tempo.

O que acaba acontece é que algum novo código (em nosso caso, o código autogenerado que foi cuspido fora de Matisse) observa o mesmo pacote de recursos sem especificar o controle personalizado. Isso parece não ser reprodutível se você escrever um teste de unidade simples que o chama e depois sem, mas ocorre quando o aplicativo é executado de verdade. De alguma forma o cache dentro ResourceBundle ejeta o bom valor e o substitui pelo quebrado. Ainda estou para descobrir o porquê e os arquivos JAR da Sun foram compilados sem informações de depuração, por isso depurar é uma tarefa árdua.

Minhas perguntas:

  1. Existe alguma maneira de definir globalmente o padrão de resourcebundle.Controle de que eu talvez não esteja ciente? Isso resolveria tudo de maneira bastante elegante.

  2. Existe alguma outra maneira de lidar com esse tipo de coisa elegantemente, talvez sem adulterar as aulas do ResourceBundle?

Foi útil?

Solução

Eu acho que essa é uma falha fundamental na maneira como os recursos de recursos são projetados para funcionar: chaves que referenciam outras chaves violam automaticamente o princípio seco (não se repete). A maneira como eu adquiri isso foi semelhante ao seu método: crie uma classe RefliceResourceBundle que permite especificar teclas de recursos nas mensagens usando o EL Notation.

O CAMINHO ERRADO:

my.name.first=Bob
my.name.last=Smith
my.name.full=Bob Smith

Da maneira certa:

my.name.first=Bob
my.name.last=Smith
my.name.full=${my.name.first} ${my.name.last}

Eu tenho Carregou o código para o GitHub Então você ou qualquer outra pessoa pode baixá -lo. Além disso, adicionei algum código de exemplo para qualquer pessoa que use a estrutura do Stripes (http://www.stripesframework.org/) para você fazer você rapidamente em ascensão.

O truque para fazer isso funcionar com o JSTL FMT Taglibs padrão foi configurar um interceptador que substituiu o recurso do HttpServletRequest por nosso. O código se parece com o seguinte:

ResourceBundle bundle = MyStaticResourceHoldingTheBundle.getBundle();
Config.set(request, Config.FMT_LOCALIZATION_CONTEXT, new LocalizationContext(bundle, locale));

Dê uma olhada no pacote Stripes.Interceptor no link acima para obter mais detalhes.

Outras dicas

Se as repetições de string estiverem localizadas no sentido de que você sabe que uma certa string será repetida, mas apenas dentro do mesmo projeto, de modo que o compartilhamento de pacotes de recursos não seja um pesadelo de design, considere dividir as cordas em várias peças de valor-chave. Separe as peças que se repetem daquelas que não o fazem e reutilizem as peças repetidas. Por exemplo, digamos que você tenha as duas seqüências seguintes que você precisa exibir:

  1. "O Robin de Chapada Vermelha é um pequeno pássaro de passerina nativo da Austrália".
  2. "O robin de tampa vermelha é encontrada em regiões mais secas em grande parte do continente".

O pacote de recursos pode ser o seguinte:

robin.name=The Red-capped Robin
robin.native=is a small passerine bird native to Australia.
robin.region=is found in dryer regions across much of the continent.

e depois combine as peças necessárias quando necessário bundle.getString("robin.name")+bundle.getString(robin.native).

Uma coisa com a qual você precisa ter cuidado é que as regras gramaticais, como a ordem do predicado, etc. pode não ser o mesmo em todos os idiomas. Então você precisaria ter um pouco de cuidado ao dividir frases.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top