Свойства Java, содержащие переменные, разделенные долларами - PullRequest
4 голосов
/ 14 октября 2011

Я храню настройки своего приложения в файле свойств, который я использую в 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()?

Ответы [ 2 ]

6 голосов
/ 14 октября 2011

Я не думаю, что это особенно "увлекательно", это работает в Ant - Ant специально написан для этого :

Свойства - это пары ключ-значение, гдеApache Ant пытается развернуть ${key} до значения во время выполнения.

и

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

Если вам нужно такое же поведение, вам необходимо реализовать логику того же рода.Вполне возможно, что вы можете использовать классы из Ant напрямую, если они делают то, что вы хотите - и если вы счастливы отправлять соответствующие двоичные файлы (и соблюдать лицензию).

В противном случае вы можете захотетьиспользуйте регулярное выражение, чтобы найти все совпадения - или (возможно, проще) переберите все системные свойства и просто замените их.

2 голосов
/ 15 октября 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);
        }
    }
}
...