"Un'-escalate strings from Eclipse or Intellij

I have a set of lines in a properties file that I want to "un-externalize", that is, embedded in my code.

I see that both Eclipse and Intellij have great support for externalizing strings from code, but does any of them support binding strings from a property file back to code?

For example, if I have a code -

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"); 
+4
source share
5 answers

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 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 have to do is call this java program with the location of the properties file and the name of the java file you want to create that will contain the properties.

For example, this properties 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 asked now. You can use my code to do what you want if you cover a bit of regular expression magic. Suppose you have a java_test file on top. Copy the built-in properties into the file that you want to replace with the code myResourceBundle.

For instance,

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 use eclipse (any modern IDE should do this), go to the Edit menu β†’ Find / Replace. In the window you will see the checkbox "Regular Expressions", check this. Now enter the following text into the search field:

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

And backward link

 \1 

in replacement.

Now click "Replace All" and voila! The code should be built into 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); } } 
+4
source

Maybe if you can explain how you need it, then you can get the right answer.

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

A more complex answer is this.

1_ First, I will recompile all the code that reads the properties file into one class (or a module called PropertyFileReader).

2_ I will create a module for reading the properties file, which will iterate over all the keys in the properties files, and then save them on the map.

4_ I can either create static map objects with filled values, or create a permanent class from it. Then I replaced the logic in the property file reader to use the map get or static class, rather than reading the property file.

5_ Once I am sure that the application is working fine. (Checking if all my unit tests pass), I delete my property files.

Note. If you use spring, then there is an easy way to separate all the key-value pairs of a property from a list of property files. Let me know if you use spring.

+1
source

You can use the Eclipse widget "Externalize Strings". It can also be used for non-externalization. Select the desired line and click the "Internalization" button. If the string was previously escalated, it will be returned and deleted from the messages.properties file.

+1
source

I would recommend something else: split the outer lines into localizable and non-localizable property files. It would probably be easier to transfer some lines to another file than to transfer them back to the source code (which, by the way, will damage maintainability).

Of course, you can write a simple (to some extent) Perl (or something else) script that will look for calls to resource packages and enter a constant in this place ... In other words, I have not heard about the mechanisms of de-externalization , you need to do it manually (or write an automatic script yourself).

0
source

Amazing oneliner from @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 sed 's|^\([^=]*\)=\(.*\)| s@Messages.getString ("\1")@"\2"@g|;s/\\/\\\\/g' messages.properties | sed -i -f - *.java run this inside your src directory and see the magic.

0
source

Source: https://habr.com/ru/post/1336552/


All Articles