Использование Groovy для раскрытия переменных в свойствах Java

Я часто использую стандартные файлы свойств Java для настройки приложений Groovy. Одна функция, которой мне не хватало, — это возможность использовать переменные как часть значения свойства, чтобы их можно было динамически расширять во время использования. Я думал, что смогу обеспечить эту функциональность, используя следующий дизайн:

  1. Используйте специальный формат, чтобы аннотировать свойства, которые должны быть развернуты. Я решил заключать такие шаблоны в двойные восклицательные знаки (!!). Эти значения свойств, по сути, являются шаблоном, который нужно расширить с помощью локальных переменных.
  2. Прежде чем использовать свойства в приложении, используйте метод groovy 'evaluate', чтобы расширить переменные приложения в шаблоне.
  3. Повторно назначьте исходный ключ свойства новому значению перед использованием.

Итак, если у меня есть файл свойств config.properties с такими свойствами, как:

version=2.3
local_lib=!!${env['GROOVY_HOME']}/${configProps.getProperty('version')}/lib!!

Свойство local_lib будет расширено из переменной среды GROOVY_HOME и значения свойства version.

В моем приложении я закодировал это следующим образом:

//Load the environment variables and configuration file
env=System.getenv()
configFile=new File('config.properties')
configProps= new Properties()
configProps.load(configFile.newDataInputStream())

//Replace configuration property values with their expanded equivalent
configProps.each{
  //if a property value is a template we evaluate it
  if (it.value.startsWith('!!')){
    valTemplate=it.value.replace('!!','"')
    it.value=evaluate(valTemplate)
  }
}

 //then we use the expanded property values 

Кажется, это работает. Когда я делаю

println configProps

Я вижу, что значение расширено, а не равно null

Однако метод getProperty для развернутого свойства возвращает значение null.

assert configProps.getProperty('local_lib')=='C:\\DEVTOOLS\\groovy-2.4.7/2.3/lib'
   |           |                       |
   |           null                    false
   [local_lib:C:\DEVTOOLS\groovy-2.4.7/2.3/lib, version:2.3]

Чем вызвано это несоответствие? Я бы ожидал вернуть значение, показанное на карте свойств.


person Ioannis K. Moutsatsos    schedule 19.08.2016    source источник


Ответы (1)


Ваше значение local_lib выглядит как String, но это не так. Это GString, только лениво приводимое к String по мере необходимости (например, при печати значения карты configProps).

Таким образом, здесь вступает в силу малоизвестный эффект Properties.getProperty(). Если фактическое значение карты не является строкой, Properties.getProperty() возвращает null.

Таким образом, чтобы получить желаемое поведение, вам нужно принудить GString к String, прежде чем вы сохраните значение в карте свойств. Вот так:

it.value=evaluate(valTemplate).toString()

or

it.value=evaluate(valTemplate) as String

Затем вы должны увидеть желаемые результаты ниже по течению.

person BalRog    schedule 19.08.2016
comment
Между прочим, именно по этой причине я избегаю использования Properties.getProperty() и Properties.setProperty() в Groovy. Я предпочитаю использовать синтаксис и семантику карты при работе с объектами Properties. - person BalRog; 19.08.2016
comment
О, действительно, принуждение @BalRog к String решает проблему. Спасибо! - person Ioannis K. Moutsatsos; 19.08.2016