Существует ли полуавтоматический способ выполнения извлечения строк для 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 долларов и отправьте мне свою базу кода, я сделаю это за вас.:)