4

プロパティファイルに「外部化解除」したい、つまりコードにインラインしたい文字列がたくさんあります。

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

5 に答える 5

4

これを行うために使用できる簡単な 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);

    }
}
于 2011-01-28T19:39:01.510 に答える
2

Eclipse の「Externalize Strings」ウィジェットを使用できます。非外部化にも使用できます。必要な文字列を選択し、「Internalize」ボタンを押します。文字列が以前に外部化されていた場合は、元に戻され、messages.properties ファイルから削除されます。

于 2013-04-30T12:26:44.580 に答える
1

これをどのように行う必要があるかを説明できれば、正しい答えが得られるかもしれません。

特にIntellijでは、あなたの質問に対する短い答えはノーです(私は日食について十分に知りません)。もちろん、少し長くなりますが、まだあまり役に立たない答えは、プラグインを作成することです。(これは、プロパティ ファイルのリストを取得し、マップ内のキーと値を読み取り、ResourceBundle.getValue("Key") を Map からの値 (キー用) に置き換える正規表現を実行します。このプラグインを作成します。私自身、あなたが私を納得させることができれば、この要件を持っているあなたのような人がもっといる.)

より精巧な答えはこれです。

1_ 最初に、プロパティ ファイルの読み取りを実行するすべてのコードを 1 つのクラス (または PropertyFileReader というモジュール) にリファクタリングします。

2_ プロパティ ファイル内のすべてのキーを反復処理し、それらの情報をマップに格納するプロパティ ファイル リーダー モジュールを作成します。

4_ 入力された値を使用して静的マップ オブジェクトを作成するか、そこから定数クラスを作成できます。次に、プロパティ ファイル リーダー モジュールのロジックを、プロパティ ファイルの読み取りではなく、マップまたは静的クラスの取得を使用するように置き換えます。

5_ アプリケーションが正常に動作することを確認したら (すべてのユニット テストに合格したかどうかを確認して)、プロパティ ファイルを削除します。

注: Spring を使用している場合は、プロパティ ファイルのリストからすべてのプロパティ キーと値のペアを分割する簡単な方法があります。スプリングを使用する場合はお知らせください。

于 2011-01-25T08:22:46.940 に答える
0

別のことをお勧めします。外部化された文字列をローカライズ可能なプロパティ ファイルとローカライズできないプロパティ ファイルに分割します。一部の文字列をソース コードに戻すよりも、別のファイルに移動する方がおそらく簡単です (ちなみに、保守性が損なわれます)。

もちろん、リソースバンドルへの呼び出しを検索し、この場所に定数を導入する単純な (ある程度) Perl (またはその他の) スクリプトを作成することもできます...つまり、非外部化メカニズムについて聞いたことがありません。手動で行う必要があります (または、自動化されたスクリプトを自分で作成します)。

于 2011-01-22T14:58:12.617 に答える
0

@potong の素晴らしいワンライナーsed 's|^\([^=]*\)=\(.*\)|s@Messages.getString("\1")@"\2"@g|;s/\\/\\\\/g' messages.properties | sed -i -f - *.javaがこれを src dir 内で実行し、魔法を見てください。

于 2012-04-04T01:15:58.463 に答える