Формат файла cfx
Файл предназначен для загрузки объектов jandcode.commons.conf.Conf
.
Расширение файла .cfx
.
Содержимое файла в формате xml
.
Корневой элемент xml описывает свойства загружаемого объекта.
Тег без атрибутов
Тег без атрибутов и без дочерних тегов, но с текстом - простое свойство объекта:
<root>
<prop1>value1</prop1>
<prop2>value2</prop2>
</root>
получаем:
{
prop1: value1
prop2: value2
}
Тег c атрибутами
Если тег с атрибутами, то имя тега рассматривается как имя свойства типа Conf, а все атрибуты - его свойства:
<root>
<obj attr1="1" attr2="2"/>
</root>
получаем:
{
obj: {
attr1: 1
attr2: 2
}
}
Пустой тег
Если тег пустой (нет атрибутов, нет дочерних, нет текста), то имя тега рассматривается как имя свойства типа Conf без атрибутов:
<root>
<obj1/>
<obj2/>
</root>
получаем:
{
obj1: {
}
obj2: {
}
}
Дочерние теги
Дочерние теги рассматриваются как свойства объекта, чьими дочерними они являются:
<root>
<obj1>
<prop1>value1</prop1>
<emptyobj/>
<withattr attr1="1" attr2="2">
<attr3>3</attr3>
<emptyobj2/>
</withattr>
</obj1>
</root>
получаем:
{
obj1: {
prop1: value1
emptyobj: {
}
withattr: {
attr1: 1
attr2: 2
attr3: 3
emptyobj2: {
}
}
}
}
Атрибут name
Если у тега имеется атрибут name
, то тег описывается свойство со значением
атрибута name
у объекта с именем тега, где атрибут встретился:
<root>
<domain name="Domain1" domain-attr1="1">
<field name="id" field-attr1="1"/>
<field name="name1" field-attr1="2"/>
</domain>
<domain name="Domain2" domain-attr1="2">
<field name="id" field-attr1="1"/>
<field name="name2" field-attr1="2"/>
</domain>
</root>
получаем:
{
domain: {
Domain1: {
domain-attr1: 1
field: {
id: {
field-attr1: 1
}
name1: {
field-attr1: 2
}
}
}
Domain2: {
domain-attr1: 2
field: {
id: {
field-attr1: 1
}
name2: {
field-attr1: 2
}
}
}
}
}
Безымянное свойство
Если свойство имеет имя i
, то оно - безымянное и для него генерируется уникальное имя.
Предназначено для описания списков:
<root>
<list1>
<i attr1="1"/>
<i attr1="2"/>
<i attr1="3"/>
</list1>
<list1 name="i" attr1="4"/>
</root>
получаем:
{
list1: {
#0: {
attr1: 1
}
#1: {
attr1: 2
}
#2: {
attr1: 3
}
#3: {
attr1: 4
}
}
}
Специальные символы в имени
В имени свойства комбинация символов '--'
и символы '/'
, ':'
заменяются на символ '!'
. Используется для описания имен свойств с путями:
<root>
<action name="my/action1" attr1="1"/>
<action>
<my--action2 attr1="1"/>
</action>
</root>
получаем:
{
action: {
my!action1: {
attr1: 1
}
my!action2: {
attr1: 1
}
}
}
Специальный коментарий
Если коментарий начинается с символа '@'
, то его текст рассматривается как
значение атрибута comment
объекта, внутри которого встретился коментарий:
<root>
<obj1>
<!--@
comment1
-->
</obj1>
<field name="f1">
<!--@
comment2
-->
</field>
</root>
получаем:
{
obj1: {
comment: comment1
}
field: {
f1: {
comment: comment2
}
}
}
Функции
Если тег начинается с символов 'x-'
, то он описывает функцию с именем тега,
без символов 'x-'
. Такие функции обрабатываются особым способом с помощью плагинов
загрузки jandcode.commons.conf.ConfLoaderPlugin
.
Стандартные функции, доступные всегда, описаны ниже.
Функция: include
Загружает файлы в объект, внутри которого описана функция. Файл грузится в один объект только один раз. При повторной загрузке - игнорируется.
Параметры:
path
- путь до включаемого файла относительно текущего загружаемого. Может включать маски, как в ant ('*'
,'**'
) для загрузки группы файловrequired
- по умолчаниюtrue
. При значении true - если файл не найден, генерируется ошибка. Иначе ошибка игнорируется.
Пример:
<root>
<x-include path="data/**/*.cfx"/>
<model name="DefaultModel">
<x-include path="default-model.cfx" required="false"/>
<!-- игнорируется, повторная загрузка: -->
<x-include path="default-model.cfx" required="false"/>
</model>
</root>
Функция: set
Установить произвольные переменные, которые в дальнейшем можно использовать в
подстановках и условиях if
/if-not
<root>
<x-set var1="value1"/>
<x-set var2="value2"/>
<node1 attr1="#{var1} % #{var2}"/>
</root>
получаем:
{
node1: {
attr1: value1 % value2
}
}
Функция: set-default
Функция аналогична set
, за исключением того, что значение переменной устанавливается
только если у нее еще нет значения.
<root>
<x-set var1="value1"/>
<x-set-default var1="default-value1"/>
<x-set-default var2="default-value2"/>
<node1 attr1="#{var1} % #{var2}"/>
</root>
получаем:
{
node1: {
attr1: value1 % default-value2
}
}
Функция: if
Загружает тело тега в объект, если соблюдается условие. Условием является набор атрибутов. Каждый атрибут рассматривается как условие, где имя атрибута - имя переменной, значение атрибута - значение, которое должно быть у переменной.
<root>
<x-set var1="value1"/>
<node1>
<x-if var1="value1">
<node-for-value1/>
</x-if>
</node1>
</root>
получаем:
{
node1: {
node-for-value1: {
}
}
}
Функция: if-not
То же, что и if
, только проверяется несоблюдение условия.
Подстановки
В значениях атрибутов раскрываются подстановки #{VAR}
.
Значения для переменных предоставляются плагинами
загрузки jandcode.commons.conf.ConfLoaderPlugin
.
Стандартные переменные, доступные всегда:
path
- абсолютный путь до текущего файла. Если текущий путь в VFS (например внутри jar), то и результат будет в формате VFS. Соответственно для реальной файловой системы путь будет в формате реальной файловой системыдругое
- значение соответствующей системной переменной изSystem.getProperties()
В описаниях подстановок используются термины:
- текущий файл - файл, в котором встретилась подстановка
- текущий каталог - каталог, в котором лежит файл в котором встретилась подстановка
Пример:
<root>
<!-- attr1 равен пути, в котором лежит текущий файл -->
<n1 attr1="#{path}"/>
<!-- attr1 равен пути в временном каталоге d:\temp\myproject\myfile.txt -->
<n3 attr1="#{java.io.tmpdir}/myproject/myfile.txt"/>
</root>