5

私は Apache Commons Configuration を使用してプロパティ ファイルを読み取っています。変数補間を完全に実行でき、多値プロパティをリストとして取得することもできます。ただし、複数の値を持つプロパティを正しく読み込むことができませんでした。そのうちの 1 つが別の多値プロパティへの参照 (変数補間) です。

プロパティ ファイルの例を次に示します (カンマ区切りの構文も試しました)。

doc.mime=application/msword
doc.mime=application/vnd.openxmlformats-officedocument.wordprocessingml.document
doc.mime=${office.mime}

office.mime=application/x-tika-msoffice
office.mime=application/x-tika-ooxml

そして、私はそれからどのように読んだか:

Configuration config = new PropertiesConfiguration("myFile");
final String[] mimesArray = config.getStringArray("doc.mime");
for(String mime : mimesArray) System.out.println(mime);
final List<Object> mimesList = config.getList("doc.mime");
System.out.println(mimesList);

これは、いずれかの方法 (getStringArrayおよびgetList)で取得したコンテンツです。

[application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/x-tika-msoffice]

これは私が予想したものとは異なります: 両方の完全なdoc.mime内容office.mime

私の他のリストの値のリスト全体を補間できるかどうかは誰にもわかりませんか? もしそうなら、それはどのように行われますか?

4

2 に答える 2

5

Commons Configuration の機能

お気づきのように、複数値のプロパティを補間する場合、Commons 構成はそのプロパティの最初の値のみを解決します。AbstractConfiguration#resolveContainerStore() 行 1177のコードを参照してください。

関連する問題がいくつか見つかりました。

CONFIGURATION-28 : 誰かが、あなたが望むものと正反対のものを欲しがる (そして手に入れる): 複数値を持つプロパティの最初の値だけ。

CONFIGURATION-55 : 多値プロパティの補間に関する詳細:

期待される結果は具体的なユースケースに大きく依存するため、この問題の正しい解決策はおそらくありません。

回避策: 2 つのリストをコードで結合する

補間をカスタマイズするよりも間違いなく簡単です:

List<Object> mimesList = config.getList("doc.mime");
List<Object> officeList = config.getList("office.mime");
mimesList.addAll(officeList);
System.out.println(mimesList);

Commons Configuration プロジェクトでこの問題を提起してください

可変補間システム全体を変更するのはおそらく難しいでしょう。しかし、彼らは少なくともドキュメントを明確にすることができました.

于 2012-02-23T09:46:26.043 に答える
1

まあ、私はこの機能が必要でした: 複数の値をプロパティに関連付け、補間によってもそれらすべてを取得できるようにするためです。

そこで、カスタム補間クラスとカスタム プロパティ構成を作成しました。バックスラッシュとデフォルトの区切り文字を含む値でもうまく機能します。

カスタム補間クラスは次のとおりです。

CustomInterPolation クラス

public class CustomInterpolation extends StrLookup {

    /*
     * (non-Javadoc)
     * 
     * @see org.apache.commons.lang.text.StrLookup#lookup(java.lang.String)
     */
    @Override
    public String lookup(String arg0) {

        String result = null;

        // Get the default delimiter.
        String delimiter = ""
                + PropertiesConfiguration.getDefaultListDelimiter();

        try {

            // Load the properties file.
            Configuration config = new PropertiesConfiguration(
                    "ressources/macro.properties");

            if (config.containsKey(arg0)) {

                // Get all values associated with the propertie.
                ArrayList<Object> values = (ArrayList<Object>) config
                        .getList(arg0);

                StringBuilder strBuild = new StringBuilder();
                Iterator<Object> itr = values.iterator();

                while (itr.hasNext()) {

                    // Append the property to the string.
                    strBuild.append((String) itr.next());

                    if (itr.hasNext()) {
                        // Adds the delimiter and backslash in order to retrieve
                        // all properties later.
                        strBuild.append("\\" + delimiter);
                    }

                }
                result = strBuild.toString();
            }

        } catch (ConfigurationException e) {
            // Nothing to do here...
        }
        // return null or all values concatenated
        return result;
    }

}

ここで、この customInterpolation クラスを正しく使用するには、カスタム プロパティ構成を使用する必要があります。

CustomPropertiesConfiguration クラス

/**
 * The Class CustomPropertiesConfiguration.
 */
public class CustomPropertiesConfiguration extends PropertiesConfiguration {

    private String delimiter;

    /**
     * Instantiates a new custom properties configuration.
     */
    public CustomPropertiesConfiguration() {
        super();
        delimiter = PropertiesConfiguration.getDefaultListDelimiter()
                + "";
    }

    /**
     * Instantiates a new custom properties configuration.
     *
     * @param file the file
     * @throws ConfigurationException the configuration exception
     */
    public CustomPropertiesConfiguration (File file) throws ConfigurationException{
        super(file);
        delimiter = PropertiesConfiguration.getDefaultListDelimiter()
                + "";
    }

    /**
     * Instantiates a new custom properties configuration.
     *
     * @param fileName the file name
     * @throws ConfigurationException the configuration exception
     */
    public CustomPropertiesConfiguration(String fileName) throws ConfigurationException {
        super(fileName);
        delimiter = PropertiesConfiguration.getDefaultListDelimiter()
                + "";
    }

    /**
     * Instantiates a new custom properties configuration.
     *
     * @param url the url
     * @throws ConfigurationException the configuration exception
     */
    public CustomPropertiesConfiguration(URL url) throws ConfigurationException{
        super(url);
        delimiter = PropertiesConfiguration.getDefaultListDelimiter()
                + "";
    }

    /* (non-Javadoc)
     * @see org.apache.commons.configuration.AbstractConfiguration#getList(java.lang.String)
     */
    @Override
    public List<Object> getList(String key) {

        // Get the list of values associated with the property
        // Implicit call to the custom interpolation class
        List<Object> properties = super.getList(key);


        ArrayList<Object> extendedProperties = new ArrayList<Object>();

        Iterator<Object> itrProperties = properties.iterator();
        // Go through all properties and retrieve values concatenated by the custom interpolation
        while (itrProperties.hasNext()) {

            String propertie = (String) itrProperties.next();

            if (propertie.contains(delimiter)) {

                //Split concatenated values.
                String[] extendedPropertiesTab = propertie.split("\\\\"+delimiter);

                // Add the retrieved values to the list of values.
                for (int i = 0; i< extendedPropertiesTab.length; ++i){
                    extendedProperties.add(extendedPropertiesTab[i]);
                }

            } else {
                extendedProperties.add(propertie);
            }

        }
        return extendedProperties;
    }

} 

そして、ここに小さなメインクラスがあります:

public class TestMacro {

    /**
     * @param args
     */
    public static void main(String[] args) {

        // Load properties file :

        try {

            // Add an interpolation to the configuration.
            // The string "custom" will be used to find value to interpolate
            // with the custom interpolation
            ConfigurationInterpolator.registerGlobalLookup("custom",
                    new CustomInterpolation());

            // Set the properties configuration.
            Configuration config = new CustomPropertiesConfiguration(
                    "ressources/macro.properties");

            String baseProp = "base.prop";
            String firstProp = "first.prop";
            String secondProp = "second.prop";

            ArrayList<Object> values = (ArrayList<Object>) config
                    .getList(baseProp);
            System.out.println(baseProp + "=>");
            for (int i = 0; i < values.size(); ++i) {
                System.out.println("[" + i + "]" + values.get(i));
            }

            System.out.println();

            values = (ArrayList<Object>) config.getList(firstProp);
            System.out.println(firstProp + "=>");
            for (int i = 0; i < values.size(); ++i) {
                System.out.println("[" + i + "]" + values.get(i));
            }

            System.out.println();

            values = (ArrayList<Object>) config.getList(secondProp);
            System.out.println(secondProp + "=>");
            for (int i = 0; i < values.size(); ++i) {
                System.out.println("[" + i + "]" + values.get(i));
            }

        } catch (ConfigurationException e) {
            e.printStackTrace();
        }

    }
}

テストでは、次のプロパティ ファイルを使用しました。

base.prop = /base, /root\\\\\\\\, t\\,t\\,t\\,t\\,
first.prop = ${custom:base.prop}, /first\\,/base
second.prop = ${custom:first.prop}, /second

そして、次の出力が得られます。

base.prop=>
[0]/base
[1]/root\\
[2]t,t,t,t,

first.prop=>
[0]/base
[1]/root\\
[2]t,t,t,t,
[3]/first,/base

second.prop=>
[0]/base
[1]/root\\
[2]t,t,t,t,
[3]/first,/base
[4]/second

ご覧のとおり、このソリューションでは、バックスラッシュとデフォルトの区切り文字「,」を使用してプロパティの値を処理できます。この 2 つの要素を含む一部のパターンは正しく処理されない可能性がありますが、このソリューションは基本的な値を処理する必要があります。

于 2014-07-02T13:33:58.047 に答える