Существует ли полуавтоматический способ выполнения извлечения строк для i18n?

У нас есть проект Java, который содержит большое количество строк на английском языке для пользовательских запросов, сообщений об ошибках и т.д. Мы хотим извлечь все переводимые строки в файл свойств, чтобы их можно было перевести позже.

Например, мы хотели бы заменить:

Foo.java

String msg = "Hello, " + name + "! Today is " + dayOfWeek;

с:

Foo.java

String msg = Language.getString("foo.hello", name, dayOfWeek);

language.properties

foo.hello = Hello, {0}! Today is {1}

Я понимаю, что делать это полностью автоматическим способом практически невозможно, так как не каждая строка должна быть переведена. Однако нам было интересно, есть ли полуавтоматический способ, который устраняет некоторые трудоемкости.

Ответ 1

То, что вы хотите, - это инструмент, который заменяет каждое выражение, включающее конкатенации строк, вызовом библиотеки, с очевидным частным случаем выражений, содержащим только одну литеральную строку.

Система преобразования программ, в которой вы можете выразить желаемые шаблоны, может это сделать. Такая система принимает правила в виде:

         lhs_pattern -> rhs_pattern  if condition ;

где шаблоны представляют собой фрагменты кода с ограничениями категории синтаксиса для переменных шаблона. Это заставляет инструмент искать синтаксис, сопоставляющий lhs_pattern, и если он найден, замените его на rhs_pattern, где соответствие шаблону выполняется поверх структур langauge, а не текста. Таким образом, он работает независимо от форматирования кода, отступов, комментариев и т.д.

Набросание нескольких правил (и упрощение, чтобы сохранить это короткое) следуя стилю вашего примера:

  domain Java;

  nationalize_literal(s1:literal_string):
    " \s1 " -> "Language.getString1(\s1 )";

  nationalize_single_concatenation(s1:literal_string,s2:term):
    " \s1 + \s2 " -> "Language.getString1(\s1) + \s2"; 

  nationalize_double_concatenation(s1:literal_string,s2:term,s3:literal_string): 
      " \s1 + \s2 + \s3 " -> 
      "Language.getString3(\generate_template1\(\s1 + "{1}" +\s3\, s2);"
   if IsNotLiteral(s2);

Образцы сами заключены в "..."; это не строковые литералы Java, а скорее способ сказать механизму, совместимому с несколькими компьютерами что суффикс внутри "..." является (доменным) кодом Java. Метафайлы отмечены символом \,  например, metavariables\s1,\s2,\s3 и вызов встроенного шаблона\сгенерировать с (и), чтобы обозначить его список метапараметров: -}

Обратите внимание на использование ограничений категории синтаксиса для метапеременных s1 и s3 для обеспечения соответствия только строковых литералов. То, что мета-переменные соответствуют шаблону с левой стороны, заменяется с правой стороны.

Sub-pattern generate_template - это процедура, которая во время преобразования (например, когда правило срабатывает) оценивает свой первый аргумент, который должен быть константой, в строку шаблона, которую вы предложили, и вставляет в вашу библиотеку, и возвращает библиотеку строковый индекс. Обратите внимание, что первый аргумент для генерации шаблона состоит в том, что этот пример состоит исключительно из конкатенированных литералов.

Очевидно, кому-то придется вручную обрабатывать шаблонные строки, которые попадают в библиотеку для создания эквивалентов на иностранном языке.
Вы правы в том, что это может привести к шаблонизации кода, потому что некоторые строки не должны помещаться в национализированную библиотеку строк. В той степени, в которой вы можете писать программные проверки для этих случаев, они могут быть включены как условия в правила, чтобы предотвратить их запуск. (С небольшим усилием вы можете поместить нетрансформированный текст в комментарий, что упростит отдельные преобразования позже).

Реально, я бы предположил, что вам нужно закодировать ~ 100 правил, подобных этому, чтобы охватить комбинаторика и особые случаи интересов. Выплата заключается в том, что ваш код автоматически увеличивается. Если все сделано правильно, вы можете повторно применить это преобразование к своему коду, поскольку ваш код проходит через несколько выпусков; он оставил бы только национализированные выражения в одиночку и только пересмотрел новые, вставленные счастливыми программистами.

Система, которая может это сделать, это DMS Software Reengineering Toolkit. DMS может анализировать/сопоставлять шаблоны/преобразовывать/выделять многие langauges, включая Java и С#.

Ответ 2

Eclipse будет вытеснять каждую отдельную строку и не будет автоматически строить подстановку, как вы ищите. Если у вас очень последовательное соглашение о том, как вы создаете свои строки, вы можете написать perl script, чтобы сделать некоторую интеллектуальную замену на .java файлах. Но этот script будет довольно сложным, если вы хотите обрабатывать

  • String msg = new String ( "Hello" );
  • Строка msg2 = "Hello2";
  • String msg3 = new StringBuffer(). append ( "Hello3" ). toString();
  • String msg4 = "Hello" + 4;
  • и др.

Я думаю, что есть некоторые платные инструменты, которые могут помочь в этом. Я помню, как оцениваю его, но я не помню его имени. Я также не помню, мог ли он обрабатывать подстановку переменных во внешних строках. Я попытаюсь найти информацию и отредактировать этот пост с подробностями.

EDIT: Инструмент был Globalyzer от Lingport. На веб-сайте говорится, что он поддерживает строчную экрнализацию, но не конкретно. Не уверен, поддерживает ли он переменную замену. Существует бесплатная пробная версия, поэтому вы можете попробовать и посмотреть.

Ответ 3

Как и эквалайзер строки Eclipse, который генерирует файлы свойств, Eclipse имеет предупреждение для неэкранных строк, что полезно для поиска файлов, которые вы не интернационализировали.

String msg = "Hello " + name;

выдает предупреждение "Нетерминированный строковый литерал, за ним следует // $NON-NLS- $". Для строк, которые действительно принадлежат к коду, вы можете добавить аннотацию (@SuppressWarnings("nls")) или добавить комментарий:

String msg = "Hello " + name; //$NON-NLS-1$

Это очень полезно для преобразования проекта в соответствующую интернационализацию.

Ответ 4

Globalyzer обладает обширными возможностями для обнаружения, управления и экстернализации строк и ускорения работы за счет просмотра строк и экстернализации один за другим. Вы можете фильтровать строки так же, как видеть их в контексте, а затем либо экстернализировать один за другим, либо партиями. Он работает с широким спектром языков программирования и типов ресурсов, включая Java. Plus Globalyzer находит гораздо больше, чем встроенные строки для ваших проектов интернационализации. Вы можете прочитать больше на http://lingoport.com/globalyzer, и там есть ссылки для регистрации для демонстрационной учетной записи. Globalyzer был впервые создан для выполнения крупных проектов интернационализации услуг, а затем за эти годы он вырос до полномасштабного корпоративного инструмента для обеспечения того, чтобы развитие получило и остается интернационализированным.

Ответ 5

Я думаю, что eclipse имеет возможность экпортировать все строки в файл свойств.

Ответ 6

Идея InteliJ - это еще один инструмент, который имеет эту функцию.

alt text

Здесь ссылка на демо

Ответ 7

Вы можете использовать метод "Externalize String" из eclipse. Откройте файл Java в редакторе, а затем нажмите "Внешняя строка" в главном меню "Источник". IT создает файл свойств для вас со всеми strng, которые вы проверили в выборе.

Надеюсь, что это поможет.

Ответ 8

поскольку все взвешиваются в IDE, я думаю, мне лучше встать на Netbeans:)

Инструменты → Интернационализация → Мастер интернационализации

очень удобно..

Ответ 9

Нельзя слишком сложно писать Python или Perl script, чтобы пересечь филеструктуру и заменить все строки в .java файлах с довольно хорошим коэффициентом успеха. Первые несколько сборок неизбежно потерпят неудачу, но вы можете посмотреть, где это произошло, и исправить это, и после нескольких повторений этого вы должны соответствовать достаточно, чтобы оставшиеся сбои можно было очистить вручную.

Если вы заплатите мне 100 долларов и отправьте мне свою базу кода, я сделаю это за вас.:)