'Un'-从 Eclipse 或 Intellij 外部化字符串

发布于 2024-10-13 23:09:33 字数 488 浏览 8 评论 0原文

我的属性文件中有一堆字符串,我想将其“非外部化”,即内联到我的代码中。

我发现 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");

I have a bunch of strings in a properties file which i want to 'un-externalize', ie inline into my code.

I see that both Eclipse and Intellij have great support to 'externalize' strings from within code, however do any of them support inlining strings from a properties file back into code?

For example if I have code like -

My.java

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

My.properties

key=a whole bunch of text

I want my java code to be replaced as -

My.java

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

始于初秋 2024-10-20 23:09:33

我编写了一个简单的 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";
}

希望这就是您所需要的!

编辑:

我明白你现在的要求。如果你施展一点正则表达式的魔力,你可以使用我的代码来做你想做的事情。假设您有上面的 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 都应该能够执行此操作),请转到“编辑菜单”->“查找/替换。在窗口中,您应该看到一个“正则表达式”复选框,选中它。现在将以下文本输入到“查找”文本区域:

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);

    }
}

I wrote a simple java program that you can use to do this.

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);
            }
        }
    }
}

Basically, all you need to do is call this java program with the location of the property file and the name of the java file you want to create that will contain the properties.

For instance this property file:

test.properties

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

will become:

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";
}

Hope this is what you need!

EDIT:

I understand what you requested now. You can use my code to do what you want if you sprinkle a bit of regex magic. Lets say you have the java_test file from above. Copy the inlined properties into the file you want to replace the myResourceBundle code with.

For example,

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"));

    }
}

Ok, now if you are using eclipse (any modern IDE should be able to do this) go to the Edit Menu -> Find/Replace. In the window, you should see a "Regular Expressions" checkbox, check that. Now input the following text into the Find text area:

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

And the back reference

\1

into the replace.

Now click "Replace all" and voila! The code should have been inlined to your needs.

Now TestFile.java will become:

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);

    }
}
望她远 2024-10-20 23:09:33

您可以使用 Eclipse“Externalize Strings”小部件。它还可以用于非外化。选择所需的字符串并按“内部化”按钮。如果该字符串之前被外部化,它将被放回 messages.properties 文件中并删除。

You may use Eclipse "Externalize Strings" widget. It can also be used for un-externalization. Select required string(s) and press "Internalize" button. If the string was externalized before, it'll be put back and removed from messages.properties file.

凡尘雨 2024-10-20 23:09:33

如果您能解释一下您需要如何执行此操作,那么您可能会得到正确的答案。

对你的问题的简短回答是否定的,尤其是在 Intellij 中(我对 eclipse 不太了解)。当然,稍长但仍然不是很有用的答案是编写一个插件。 (这将获取属性文件列表并读取映射中的键和值,然后用正则表达式替换 ResourceBundle.getValue("Key") 与映射中的值(对于键)。我将编写此插件我自己,如果你能让我相信,还有更多像你这样的人有这个要求。)

更详细的答案是这样的。

1_ 首先,我将重构所有执行属性文件读取的代码到单个类(或名为 PropertyFileReader 的模块)。

2_ 我将创建一个属性文件读取器模块,该模块迭代属性文件中的所有键,然后将这些信息存储在映射中。

4_ 我可以使用填充的值创建静态地图对象,也可以从中创建一个常量类。然后,我将替换属性文件读取器模块中的逻辑,以使用地图或静态类上的 get 而不是属性文件读取。

5_ 一旦我确定应用程序执行正常(通过检查我的所有单元测试是否通过),那么我将删除我的属性文件。

注意:如果您使用的是 spring,那么有一种简单的方法可以从属性文件列表中拆分出所有属性键值对。如果您使用弹簧,请告诉我。

May be if you can explain on how you need to do this, then you could get the correct answer.

The Short answer to your question is no, especially in Intellij (I do not know enough about eclipse). Of course the slightly longer but still not very useful answer is to write a plugin. ( That will take a list of property files and read the key and values in a map and then does a regular expression replace of ResourceBundle.getValue("Key") with the value from Map (for the key). I will write this plugin myself, if you can convince me that, there are more people like you, who have this requirement.)

The more elaborate answer is this.

1_ First I will re-factor all the code that performs property file reading to a single class (or module called PropertyFileReader).

2_ I will create a property file reader module, that iterates across all the keys in property file(s) and then stores those information in a map.

4_ I can either create a static map objects with the populated values or create a constant class out of it. Then I will replace the logic in the property file reader module to use a get on the map or static class rather than the property file reading.

5_ Once I am sure that the application performs ok.(By checking if all my Unit Testing passes), then I will remove my property files.

Note: If you are using spring, then there is a easy way to split out all property key-value pairs from a list of property files. Let me know if you use spring.

狠疯拽 2024-10-20 23:09:33

我会推荐其他东西:将外部化字符串拆分为可本地化和不可本地化的属性文件。将一些字符串移动到另一个文件可能比将其移回源代码更容易(顺便说一下,这会损害可维护性)。

当然,您可以编写简单的(在某种程度上)Perl(或其他)脚本,它将搜索对资源包的调用并在这个地方引入常量......
换句话说,我没有听说过去外部化机制,你需要手动完成(或者自己编写一些自动化脚本)。

I would recommend something else: split externalized strings into localizable and non-localizable properties files. It would be probably easier to move some strings to another file than moving it back to source code (which will hurt maintainability by the way).

Of course you can write simple (to some extent) Perl (or whatever) script which will search for calls to resource bundles and introduce constant in this place...
In other words, I haven't heard about de-externalizing mechanism, you need to do it by hand (or write some automated script yourself).

浪推晚风 2024-10-20 23:09:33

来自 @potong sed 的|^\([^=]*\)=\(.*\)|[电子邮件受保护]("\1")@"\2"@g|;s/\\/\\\\/g' messages.properties |
sed -i -f - *.java
在你的 src 目录中运行它,看看它的魔力。

An awesome oneliner from @potong sed 's|^\([^=]*\)=\(.*\)|[email protected]("\1")@"\2"@g|;s/\\/\\\\/g' messages.properties |
sed -i -f - *.java
run this inside your src dir, and see the magic.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文