Свойства на Java, съдържащи променливи, разделени с долари

Съхранявам настройките на приложението си във файл със свойства, който използвам в Ant и в приложението Java. Може би не е добра практика, но го намирам за много удобно за избягване на дублиране. Файлът съдържа променливи като:

usefulstuff.dir = ${user.home}/usefulstuff

Така че други хора да могат да изпълняват програмата на *nix системи, при условие че имат папката полезни неща в домашната си директория.

Сега, очарователното е, че този файл със свойства работи добре в Ant (променливата се разрешава на /home/username), докато когато зареждам същия файл директно в приложението Java, получавам низ, съдържащ ${user.home}/usefulstuff, което наистина не е много полезно.

Зареждам подпорите с този код в Ant:

   <loadproperties srcFile="myProps.properties"/>

И в приложението Java:

    FileInputStream ins = new FileInputStream(propFilePath);
    myProps.load(ins);
    ins.close();

Пропускам ли нещо? Може би има по-добър начин за зареждане на свойства в Java приложение от load()?


person Mulone    schedule 14.10.2011    source източник
comment
Свързани: stackoverflow.com/questions/1412132/ и stackoverflow.com/questions/872272/   -  person Matt Ball    schedule 14.10.2011


Отговори (2)


Не мисля, че е особено "очарователно", че това работи в Ant - Ant умишлено е написано да го прави:

Свойствата са двойки ключ-стойност, където Apache Ant се опитва да разшири ${key} до стойност по време на изпълнение.

и

Ant предоставя достъп до всички системни свойства, сякаш са били дефинирани с помощта на <property> задача. Например ${os.name} се разширява до името на операционната система.

Ако искате същото поведение, ще трябва да приложите същия вид логика. Възможно е да използвате класовете от Ant директно, ако те правят това, което искате - и ако сте доволни да изпратите съответните двоични файлове (и спазвате лиценза).

В противен случай може да искате да използвате регулярен израз, за ​​да намерите всички съвпадения - или (вероятно по-просто) да повторите всички системни свойства и да направите проста замяна върху тях.

person Jon Skeet    schedule 14.10.2011

Както каза Джон, трябва да е лесно да напишете сами обработката на собствеността. Например:

import java.util.*;

public class PropertiesTest
{
    public static void main(String[] args)
    {
        Properties props = new Properties();
        props.setProperty("foo", "foo/${os.name}/baz/${os.version}");
        props.setProperty("bar", "bar/${user.country}/baz/${user.country}");

        System.out.println("BEFORE:");
        printProperties(props);

        resolveSystemProperties(props);

        System.out.println("\n\nAFTER:");
        printProperties(props);
    }

    static void resolveSystemProperties(Properties props)
    {
        Map<String, String> sysProps = readSystemProperties();
        Set<String> sysPropRefs = sysProps.keySet();

        Enumeration names = props.propertyNames();
        while (names.hasMoreElements())
        {
            String name = (String) names.nextElement();
            String value = props.getProperty(name);
            for (String ref : sysPropRefs)
            {
                if (value.contains(ref))
                {
                    value = value.replace(ref, sysProps.get(ref));
                }
            }
            props.setProperty(name, value);
        }
    }

    static Map<String, String> readSystemProperties()
    {
        Properties props = System.getProperties();
        Map<String, String> propsMap = 
            new HashMap<String, String>(props.size());

        Enumeration names = props.propertyNames();
        while (names.hasMoreElements())
        {
            String name = (String) names.nextElement();
            propsMap.put("${" + name + "}", props.getProperty(name));
        }
        return propsMap;
    }

    static void printProperties(Properties props)
    {
        Enumeration names = props.propertyNames();
        while (names.hasMoreElements())
        {
            String name = (String) names.nextElement();
            String value = props.getProperty(name);
            System.out.println(name + " => " + value);
        }
    }
}
person Binil Thomas    schedule 14.10.2011