来自Eclipse或Intellij的’Un’-外化字符串

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

我看到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"); 

我写了一个简单的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 data = process(defaultProps,javaFile); buildFile(javaFile,data); } public static List process(Properties propsFile, File javaFile) { List data = new ArrayList(); Set> 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 aStack = new Stack(); for(Entry 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 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); } } 

如果你可以解释你需要怎么做,那么你可以得到正确的答案。

对你的问题的简短回答是否定的,特别是在Intellij中(我对eclipse知之甚少)。 当然,稍微长一点但仍然不是很有用的答案是写一个插件。 (这将获取属性文件列表并读取映射中的键和值,然后使用Map中的值(对于键)执行正则表达式替换ResourceBundle.getValue(“Key”)。我将编写此插件我自己,如果你能说服我,有更多像你这样的人,有这个要求。)

更精细的答案就是这个。

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

2_我将创建一个属性文件阅读器模块,它遍历属性文件中的所有键,然后将这些信息存储在地图中。

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

5_一旦我确定应用程序执行正常。(通过检查我的所有unit testing是否通过),然后我将删除我的属性文件。

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

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

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

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

来自@potong sed 's|^\([^=]*\)=\(.*\)|s@Messages.getString("\1")@"\2"@g|;s/\\/\\\\/g' messages.properties | sed -i -f - *.java sed 's|^\([^=]*\)=\(.*\)|s@Messages.getString("\1")@"\2"@g|;s/\\/\\\\/g' messages.properties | sed -i -f - *.java在你的src目录中运行它,看看魔术。