Подтвердить что ты не робот

Как ссылаться на другое свойство в java.util.Properties?

Может ли файл свойств Java ссылаться на файл других свойств?

## define a default directory for Input files  
dir.default=/home/data/in/

dir.proj1=${dir.default}p1
dir.proj2=${dir.default}p2
dir.proj3=${dir.default}p3

Возможно ли это?

4b9b3361

Ответ 1

Крис Майр XProperties класс может быть хорошей отправной точкой.

Вы можете заменить константу в любом месте значения свойства и даже иметь более одной константы в значении, как в следующем примере:

CONST_1 = shoes and ships
CONST_2 = sealing wax
SomeValue = {CONST_1} and {CONST_2} 

В этом примере свойство SomeValue оценивается как "обувь, корабли и сургуч".


Смотрите также: http://webcache.googleusercontent.com/search?q=cache:gCgFCpEgmsgJ:www2.sys-con.com/itsg/virtualcd/java/source/6-12/52.html+&cd=1&hl=en&ct=clnk&gl=us

Ответ 2

Eproperties - это проект с открытым исходным кодом, который обеспечивает замену переменных наряду с несколькими другими функциями, хотя замена может оказаться наиболее полезной. Это подкласс java.util.Properties и может использоваться любым другим классом, который может получать информацию о конфигурации как Свойства.

Ответ 3

Также может это сделать Commons Config lib. http://commons.apache.org/configuration/userguide/overview.html#Using_Configuration

Однако, как уже указывалось, взгляните на библиотеку EProperties; http://code.google.com/p/eproperties/

Он поддерживает ряд опрятных функций (таких как подстановка, вложенность, списки), включая включение, расширение свойств Java и немного меньший вес, чем Commons Config (который также позволяет включать свойства с использованием синтаксиса include).

Ответ 4

Стандартные файлы свойств - это только пары ключ-значение. В текстовом формате Properties просто отделяет ключ от значения и выполняет некоторые простые действия, такие как разрешение экранированных символов. Возможно, вы сможете определить объекты в подробном синтаксисе XML.

Если вам нужен собственный синтаксис подстановки, вы можете манипулировать возвращаемым значением, как и с любой другой строкой. Кроме того, вы можете написать свою собственную версию Properties или выполнить подстановку при создании файла.

Ответ 5

Класс java.util.Properties не сделает этого для вас. Было бы не слишком сложно подклассифицировать свойства, переопределить метод load() и самостоятельно выполнить подстановку.

Ответ 6

Поскольку свойства eproperties не поддерживаются, а общая конфигурация имеет зависимость от ведения журнала (что по иронии судьбы означает, что вы не можете использовать его для настройки ведения журнала), я использую этот фрагмент кода, который требует только commons-lang(3) для загрузки интерполированных свойств:

@SuppressWarnings("serial")
public static Map<String,String> loadPropertiesMap(InputStream s) throws IOException {
    final Map<String, String> ordered = new LinkedHashMap<String, String>();
    //Hack to use properties class to parse but our map for preserved order
    Properties bp = new Properties() {
        @Override
        public synchronized Object put(Object key, Object value) {
            ordered.put((String)key, (String)value);
            return super.put(key, value);
        }
    };
    bp.load(s);
    final Map<String,String> resolved = new LinkedHashMap<String, String>(ordered.size());
    StrSubstitutor sub = new StrSubstitutor(new StrLookup<String>() {
        @Override
        public String lookup(String key) {
            String value = resolved.get(key);
            if (value == null)
                return System.getProperty(key);
            return value;
        }
    });
    for (String k : ordered.keySet()) {
        String value = sub.replace(ordered.get(k));
        resolved.put(k, value);
    }
    return resolved;
}

Ввод

blah=${user.dir}
one=1
two=2
five=5
fifteen=${one}${five}
twoonefive=${two}${fifteen}
six=6

Выход

blah=/current/working/dir
one=1
two=2
five=5
fifteen=15
twoonefive=215
six=6

Очевидно, вы можете преобразовать Map<String,String> обратно в объект Properties, если вам это нужно. Я решаю, основываясь на ранее объявленных свойствах и свойствах системы, но вы, очевидно, можете изменить это в StrSubstitutor.lookup.

Ответ 7

В этом конкретном случае (и в других тоже), вам лучше решить дублирование, указав различные свойства:

  • change: dir.proj1=dir.default /p1 в dir.proj1_extension=/p1
  • prepend: dir.default до dir.proj1_extension, чтобы получить полное местоположение proj1 в вашем коде приложения.

Сделайте то же самое для других проектов.

Ответ 8

Файл конфигурации состоит из операторов в формате key=value или key:value. Их возможный путь, когда значение ключа может ссылаться на другое значение ключа. Строка между открытием "$ {" и закрытием "}" интерпретируется как ключ. Значение замещенной переменной может быть определено как системное свойство или в самом файле конфигурации.

Поскольку Properties наследуется от Hashtable, методы put и putAll могут быть применены к Properties object.

Map<String, String> map = new LinkedHashMap<String, String>();
map.put("key", "vlaue");
Properties props = new Properties();
props.putAll( map );

выработать сообщение @Adam Gent в деталях. commons-text-1.1.jar

import org.apache.commons.text.StrLookup;
import org.apache.commons.text.StrSubstitutor;

public class Properties_With_ReferedKeys {
    public static void main(String[] args) {

        ClassLoader classLoader = Properties_With_ReferedKeys.class.getClassLoader();

        String propertiesFilename = "keys_ReferedKeys.properties";
        Properties props = getMappedProperties(classLoader, propertiesFilename);

        System.out.println( props.getProperty("jdk") );

    }


    public static Properties getMappedProperties( ClassLoader classLoader, String configFilename ) {
        Properties fileProperties = new Properties();

        try {
            InputStream resourceAsStream = classLoader.getResourceAsStream( configFilename );

            Map<String, String> loadPropertiesMap = loadPropertiesMap( resourceAsStream );
            Set<String> keySet = loadPropertiesMap.keySet();
            System.out.println("Provided 'Key':'Value' pairs are...");
            for (String key : keySet) {
                System.out.println( key + " : " + loadPropertiesMap.get(key) );
            }

            fileProperties.putAll( loadPropertiesMap );
        } catch ( IOException e ) {
            e.printStackTrace();
        }

        return fileProperties;
    }
    public static Map<String,String> loadPropertiesMap( InputStream inputStream ) throws IOException {
        final Map<String, String> unResolvedProps = new LinkedHashMap<String, String>();

        /*Reads a property list (key and element pairs) from the input byte stream. 
         * The input stream is in a simple line-oriented format.
         */
        @SuppressWarnings("serial")
        Properties props = new Properties() {
            @Override
            public synchronized Object put(Object key, Object value) {
                unResolvedProps.put( (String)key, (String)value );
                return super.put( key, value );
            }
        };
        props.load( inputStream );

        final Map<String,String> resolvedProps = new LinkedHashMap<String, String>( unResolvedProps.size() );

        // Substitutes variables within a string by values.
        StrSubstitutor sub = new StrSubstitutor( new StrLookup<String>() {
            @Override
            public String lookup( String key ) {

                /*The value of the key is first searched in the configuration file,
                 * and if not found there, it is then searched in the system properties.*/
                String value = resolvedProps.get( key );

                if (value == null)
                    return System.getProperty( key );

                return value;
            }
        } );

        for ( String key : unResolvedProps.keySet() ) {

            /*Replaces all the occurrences of variables with their matching values from the resolver using the given 
             * source string as a template. By using the default ${} the corresponding value replaces the ${variableName} sequence.*/
            String value = sub.replace( unResolvedProps.get( key ) );
            resolvedProps.put( key, value );
        }
        return resolvedProps;
    }
}

Файл конфигурации "Если вы хотите, чтобы ссылка была проигнорирована и не будет заменена, вы можете использовать формат ниже.

 $${${name}} must be used for output ${ Yash }.  EX: jdk = ${jre-1.8}

Файл: keys_ReferedKeys.properties

# MySQL Key for each developer for their local machine
dbIP       = 127.0.0.1
dbName     = myApplicationDB
dbUser     = scott
dbPassword = tiger

# MySQL Properties 
# To replace fixed-keys with corresponding build environment values. like « predev,testing,preprd.
config.db.driverClassName : com.mysql.jdbc.Driver
config.db.url             : jdbc:mysql://${dbIP}:3306/${dbName}
config.db.username        : ${dbUser}
config.db.password        : ${dbPassword}

# SystemProperties
userDir      = ${user.dir}
os.name      = ${os.name}
java.version = ${java.version}
java.specification.version = ${java.specification.version}

# If you want reference to be ignored and won't be replaced.
# $${${name}} must be used for output ${ Yash }.  EX: jdk = ${jre-1.8}
jdk = $${jre-${java.specification.version}}

Пример свойств Java (ключ = значение) log4j.properties

Ответ 9

Ниже приведен фрагмент кода в Java для чтения свойств, которые ссылаются на другие свойства. В частности, это повторные запросы, но могут быть и другими.

LinkedHashMap<String, String> sqlsRaw = loadPropertiesFromFile();
LinkedHashMap<String, String> sqls = new LinkedHashMap<>();
StrSubstitutor substitutor = new StrSubstitutor(sqls);

for (Map.Entry<String, String> entry : sqlsRaw.entrySet()) {
    String sql = entry.getValue();
    try {
        sql = substitutor.replace(sql);
    } catch (Exception e) {
        throw new RuntimeException("Found an sql with a non replaced reference to another. Please validate that the required key was defined before this sql: " + entry.getValue(), e);
    }
    sqls.put(entry.getKey(), sql);
}

Свойства примера:

key1=value1
key21=value2 ${key1}

После запуска key21 будет иметь значение value2 value1.

* Использование apache StrSubstitutor.

Ответ 10

Ни одно из приведенных решений мне не очень понравилось. EProperties не поддерживается и недоступен в Maven Central. Commons Config слишком велик для этого. StrSubstitutor в общем достоянии устарел.

Мое решение опирается только на обычный текст:

public static Properties interpolateProperties(Properties rawProperties) {
    Properties newProperties = new Properties();
    interpolateProperties(rawProperties, newProperties);
    return newProperties;
}

public static void interpolateProperties(Properties rawProperties, Properties dstProperties) {
    StringSubstitutor sub = new StringSubstitutor((Map)rawProperties);
    for (Map.Entry<Object, Object> e : rawProperties.entrySet()) {
        dstProperties.put(e.getKey(), sub.replace(e.getValue()));
    }
}

то есть:

Properties props = new Properties();
props.put("another_name", "lqbweb");
props.put("car", "this is a car from ${name}");
props.put("name", "${another_name}");
System.out.println(interpolateProperties(props));

распечатывает:

{машина = это машина из рубена, имя = рубен, другое имя = рубен}

Ответ 11

У меня есть вопрос

Я не могу повторно использовать значение ключа для определения другого ключа.

Пример:

alg.Name=claims

${alg.Name}.property1=srcid,extid

${alg.Name}.returnvalue=12

Может ли кто-нибудь предложить какое-нибудь решение или помочь мне в этом?