'Un'-экстернализация строк из Eclipse или Intellij - PullRequest
4 голосов
/ 22 января 2011

У меня есть куча строк в файле свойств, которые я хочу «неэкспортировать», т. Е. Встроить в мой код.

Я вижу, что и Eclipse, и Intellij имеют отличную поддержку для «экранизации» строкизнутри кода, однако поддерживает ли какая-либо из них встраивание строк из файла свойств обратно в код?

Например, если у меня есть такой код -

My.java

System.out.println(myResourceBundle.getString("key"));

My.properties

key=a whole bunch of text

Я хочу, чтобы мой код Java был заменен на -

My.java

System.out.println("a whole bunch of text");

Ответы [ 5 ]

4 голосов
/ 28 января 2011

Я написал простую Java-программу, которую вы можете использовать для этого.

Dexternalize.java

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;


public class Deexternalize {

    public static final Logger logger = Logger.getLogger(Deexternalize.class.toString());

    public static void main(String[] args) throws IOException {
        if(args.length != 2) {
            System.out.println("Deexternalize props_file java_file_to_create");
            return;
        }

        Properties defaultProps = new Properties();
        FileInputStream in = new FileInputStream(args[0]);
        defaultProps.load(in);
        in.close();

        File javaFile = new File(args[1]);

        List<String> data = process(defaultProps,javaFile);

        buildFile(javaFile,data);

    }

    public static List<String> process(Properties propsFile, File javaFile) {
        List<String> data = new ArrayList<String>();
        Set<Entry<Object,Object>> setOfProps = propsFile.entrySet();
        int indexOf = javaFile.getName().indexOf(".");
        String javaClassName = javaFile.getName().substring(0,indexOf);

        data.add("public class " + javaClassName + " {\n");
        StringBuilder sb = null;

        // for some reason it's adding them in reverse order so putting htem on a stack
        Stack<String> aStack = new Stack<String>();

        for(Entry<Object,Object> anEntry : setOfProps) {
            sb = new StringBuilder("\tpublic static final String ");
            sb.append(anEntry.getKey().toString());
            sb.append(" = \"");
            sb.append(anEntry.getValue().toString());
            sb.append("\";\n");
            aStack.push(sb.toString());
        }

        while(!aStack.empty()) {
            data.add(aStack.pop());
        }

        if(sb != null) {
            data.add("}");
        }

        return data;
    }

    public static final void buildFile(File fileToBuild, List<String> lines) {
        BufferedWriter theWriter = null;

        try {
            // Check to make sure if the file exists already.
            if(!fileToBuild.exists()) {
                fileToBuild.createNewFile();
            }

            theWriter = new BufferedWriter(new FileWriter(fileToBuild));

            // Write the lines to the file.
            for(String theLine : lines) {
                // DO NOT ADD windows carriage return.
                if(theLine.endsWith("\r\n")){
                    theWriter.write(theLine.substring(0, theLine.length()-2));
                    theWriter.write("\n");
                } else if(theLine.endsWith("\n")) {
                    // This case is UNIX format already since we checked for
                    // the carriage return already.
                    theWriter.write(theLine);
                } else {
                    theWriter.write(theLine);
                    theWriter.write("\n");
                }
            }

        } catch(IOException ex) {
            logger.log(Level.SEVERE, null, ex);
        } finally {
            try {
                theWriter.close();
            } catch(IOException ex) {
                logger.log(Level.SEVERE, null, ex);
            }
        }
    }
}

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

Например, этот файл свойств:

test.properties

TEST_1=test test test
TEST_2=test 2456
TEST_3=123456

станет:

java_test.java

public class java_test {
    public static final String TEST_1 = "test test test";
    public static final String TEST_2 = "test 2456";
    public static final String TEST_3 = "123456";
}

Надеюсь, это то, что вам нужно!

EDIT:

Я понимаю, что вы просили сейчас. Вы можете использовать мой код, чтобы делать то, что вы хотите, если вы добавите немного магии регулярных выражений. Допустим, у вас есть файл java_test сверху. Скопируйте встроенные свойства в файл, которым вы хотите заменить код myResourceBundle.

Например,

TestFile.java

public class TestFile {

    public static final String TEST_1 = "test test test";
    public static final String TEST_2 = "test 2456";
    public static final String TEST_3 = "123456";

    public static void regexTest() {

        System.out.println(myResourceBundle.getString("TEST_1"));
        System.out.println(myResourceBundle.getString("TEST_1"));
        System.out.println(myResourceBundle.getString("TEST_3"));

    }
}

Хорошо, теперь, если вы используете eclipse (любой современный IDE должен это делать), перейдите в меню Edit -> Find / Replace. В окне вы должны увидеть флажок «Регулярные выражения», отметьте это. Теперь введите следующий текст в область «Найти текст»:

myResourceBundle\.getString\(\"(.+)\"\)

И обратная ссылка

\1

в замену.

Теперь нажмите «Заменить все» и вуаля! Код должен был соответствовать вашим потребностям.

Теперь TestFile.java станет:

TestFile.java

public class TestFile {

    public static final String TEST_1 = "test test test";
    public static final String TEST_2 = "test 2456";
    public static final String TEST_3 = "123456";

    public static void regexTest() {

        System.out.println(TEST_1);
        System.out.println(TEST_1);
        System.out.println(TEST_3);

    }
}
1 голос
/ 30 апреля 2013

Вы можете использовать виджет Eclipse "Externalize Strings". Это может также использоваться для неэкстернализации. Выберите необходимую строку (и) и нажмите кнопку «Интернализация». Если строка была выведена ранее, она будет возвращена и удалена из файла messages.properties.

1 голос
/ 25 января 2011

Может быть, если вы сможете объяснить, как вам нужно это сделать, тогда вы сможете получить правильный ответ.

Краткий ответ на ваш вопрос - нет, особенно в Intellij (я не знаю достаточно о затмении).Конечно, более длинный, но все же не очень полезный ответ - написать плагин.(Это возьмет список файлов свойств и прочитает ключ и значения на карте, а затем заменит ResourceBundle.getValue ("Key") на регулярное выражение значением из Map (для ключа). Я напишу этот плагинСам, если вы можете убедить меня, что есть больше людей, подобных вам, у которых есть это требование.)

Более сложный ответ таков:

1_ Сначала я переформулирую всекод, который выполняет чтение файла свойств в один класс (или модуль с именем PropertyFileReader).

2_ Я создам модуль чтения файла свойств, который перебирает все ключи в файле (ах) свойств, а затем сохраняет эту информациюв карте.

4_ Я могу либо создать объекты статической карты с заполненными значениями, либо создать из нее постоянный класс.Затем я заменю логику в модуле чтения файла свойств, чтобы использовать метод get on the map или static, а не чтение файла свойств.

5_ После того, как я уверен, что приложение работает нормально (проверяя,все мои модульные тесты), затем я удалю свои файлы свойств.

Примечание. Если вы используете spring, существует простой способ выделить все пары ключ-значение свойства из списка файлов свойств.,Дайте мне знать, если вы используете весну.

0 голосов
/ 04 апреля 2012

Удивительный oneliner из @potong sed 's|^\([^=]*\)=\(.*\)|s@Messages.getString("\1")@"\2"@g|;s/\\/\\\\/g' messages.properties | sed -i -f - *.java запустите его в вашем src dir и посмотрите на магию.

0 голосов
/ 22 января 2011

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

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

...