mirror of
https://gitee.com/jmix/cuba.git
synced 2024-12-03 03:38:33 +08:00
Исправлены орфографические,пунктуационные ошибки и опечатки
This commit is contained in:
parent
85ae864ede
commit
fd2c8f8725
@ -1,215 +1,215 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []>
|
||||
<!-- This document was created with Syntext Serna Free. --><chapter id="chapter_deployment" lang="ru">
|
||||
<title>Развертывание приложений</title>
|
||||
<para>На диаграмме ниже приведена возможная структура развернутого приложения, созданного на базе платформы. </para>
|
||||
<figure>
|
||||
<title>Структура CUBA-приложения</title>
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata contentwidth="80%" align="center" fileref="img/DeploymentStructure.png"/>
|
||||
</imageobject>
|
||||
</mediaobject>
|
||||
</figure>
|
||||
<para>В приведенном варианте приложение обеспечивает отсутствие единой точки отказа, балансировку нагрузки и подключение различных типов клиентов. Однако в простейшем случае серверная часть приложения может быть развернута на одном компьютере, содержащем в том числе и базу данных. </para>
|
||||
<section>
|
||||
<title>Каталоги приложения</title>
|
||||
<para>В данном разделе описываются каталоги файловой системы, используемые различными <link linkend="app_tiers">блоками приложения</link> во время выполнения.</para>
|
||||
<section id="conf_dir">
|
||||
<title>Конфигурационный каталог</title>
|
||||
<para>Каталог конфигурации предназначен для размещения ресурсов, дополняющих и переопределяющих свойства приложения, пользовательский интерфейс и бизнес-логику после развертывания приложения. Переопределение обеспечивается механизмом загрузки интерфейса инфраструктуры <code>
|
||||
<link linkend="resources">Resources</link>
|
||||
</code>, который сначала выполняет поиск в конфигурационном каталоге, а потом в CLASSPATH, так что одноименные ресурсы в конфигурационном каталоге имеют приоритет над расположенными в JAR-файлах и каталогах классов.</para>
|
||||
<para>Конфигурационный каталог может содержать следующие типы ресурсов:<itemizedlist>
|
||||
<listitem>
|
||||
<para>Файл <filename>
|
||||
<link linkend="app_properties_files">local.app.properties</link>
|
||||
</filename>, определяющий параметры развертывания блоков приложения, работающих под управлением веб-сервера</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Конфигурационные файлы <filename>
|
||||
<link linkend="metadata.xml">metadata.xml</link>
|
||||
</filename>, <filename>
|
||||
<link linkend="persistence.xml">persistence.xml</link>
|
||||
</filename>, <filename>
|
||||
<link linkend="remoting-spring.xml">remoting-spring.xml</link>
|
||||
</filename>, <filename>
|
||||
<link linkend="spring.xml">spring.xml</link>
|
||||
</filename>, <filename>
|
||||
<link linkend="views.xml">views.xml</link>
|
||||
</filename></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><link linkend="screen_xml">XML-дескрипторы</link> экранов UI</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><link linkend="screen_controller">Контроллеры</link> экранов UI в виде исходных текстов Java или Groovy</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Скрипты или классы Groovy, а также исходные тексты классов Java, используемые приложением через интерфейс <code>
|
||||
<link linkend="scripting">Scripting</link>
|
||||
</code>.</para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
<para>Расположение конфигурационного каталога определяется свойством приложения <property>
|
||||
<link linkend="cuba.confDir">cuba.confDir</link>
|
||||
</property>. Для блоков Midlleware, Web Client и Web Portal в стандартном варианте развертывания в <application>Tomcat</application> это подкаталог с именем веб-приложения в каталоге <filename>tomcat/conf</filename>.</para>
|
||||
</section>
|
||||
<section id="work_dir">
|
||||
<title>Рабочий каталог</title>
|
||||
<para>Рабочий каталог используется приложением для хранения файлов данных и конфигурации.</para>
|
||||
<para>Например, подкаталог <filename>filestorage</filename> рабочего каталога по умолчанию используется <link linkend="file_storage">хранилищем загруженных файлов</link>. Кроме того, блок Middleware на старте сохраняет в рабочем каталоге сгенерированные файлы <filename>
|
||||
<link linkend="persistence.xml">persistence.xml</link>
|
||||
</filename> и <filename>orm.xml</filename>.</para>
|
||||
<para>Расположение рабочего каталога определяется свойством приложения <property>
|
||||
<link linkend="cuba.dataDir">cuba.dataDir</link>
|
||||
</property>. Для блоков Midlleware, Web Client и Web Portal в стандартном варианте развертывания в <application>Tomcat</application> это подкаталог с именем веб-приложения в каталоге <filename>tomcat/work</filename>.</para>
|
||||
</section>
|
||||
<section id="log_dir">
|
||||
<title>Каталог журналов</title>
|
||||
<para>В каталоге журналов создаются лог-файлы приложения.</para>
|
||||
<para>Состав и настройка файлов журналов определяются конфигурацией фреймворка <application>Apache log4j</application>. Расположение файла конфигурации определяется системным свойством <literal>
|
||||
<link linkend="log4j.configuration">log4j.configuration</link>
|
||||
</literal>.</para>
|
||||
<para>Данный каталог может быть также использован для сохранения произвольной информации о выполнении приложения. Путь к каталогу журналов определяется свойством приложения <property>
|
||||
<link linkend="cuba.logDir">cuba.logDir</link>
|
||||
</property>. Для блоков Midlleware, Web Client и Web Portal в стандартном варианте развертывания в <application>Tomcat</application> это каталог <filename>tomcat/logs</filename>.</para>
|
||||
</section>
|
||||
<section id="temp_dir">
|
||||
<title>Временный каталог</title>
|
||||
<para>Данный каталог может быть использован для создания произвольных временных файлов во время выполнения приложения. Путь к временному каталогу определяется свойством приложения <property>
|
||||
<link linkend="cuba.tempDir">cuba.tempDir</link>
|
||||
</property>. Для блоков Midlleware, Web Client и Web Portal в стандартном варианте развертывания в <application>Tomcat</application> это подкаталог с именем веб-приложения в каталоге <filename>tomcat/temp</filename>.</para>
|
||||
</section>
|
||||
<section id="db_dir">
|
||||
<title>Каталог скриптов базы данных</title>
|
||||
<para>В данном каталоге развернутого блока Middleware хранится набор SQL скриптов создания и обновления БД.</para>
|
||||
<para>Структура каталога скриптов повторяет описанную в <xref linkend="db_scripts"/>, но имеет один дополнительный верхний уровень, разделяющий скрипты используемых <link linkend="base_projects">базовых проектов</link> и самого приложения. Нумерация каталогов верхнего уровня определяется во время сборки проекта.</para>
|
||||
<para>Расположение рабочего каталога определяется свойством приложения <property>
|
||||
<link linkend="cuba.dbDir">cuba.dbDir</link>
|
||||
</property>. В стандартном варианте развертывания в <application>Tomcat</application> это подкаталог <filename>WEB-INF/db</filename> каталога веб-приложения среднего слоя, например <filename>tomcat/webapps/app-core/WEB-INF/db</filename>.</para>
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
<title>Использование инструментов JMX</title>
|
||||
<section>
|
||||
<title>Встроенная JMX консоль</title>
|
||||
<para>Модуль Web Client базового проекта <structname>cuba</structname> платформы содержит средство просмотра и редактирования JMX объектов. Точкой входа в этот инструмент является экран <filename>com/haulmont/cuba/web/app/ui/jmxcontrol/browse/display-mbeans.xml</filename>, зарегистрированный под идентификатором <code>jmxcontrol$DisplayMbeans</code> и в стандартном меню доступный через пункт <guimenu>Администрирование</guimenu> -> <guimenuitem>Консоль JMX</guimenuitem>.</para>
|
||||
<para>Без дополнительной настройки консоль отображает все JMX объекты, зарегистрированные в JVM, на которой работает блок Web Client, к которому в данный момент подключен пользователь. Соответственно, в простейшем случае развертывания всех блоков приложения в одном экземпляре веб-контейнера консоль имеет доступ к JMX бинам всех уровней, а также к JMX объектам самой JVM и веб-контейнера. </para>
|
||||
<para>Имена бинов приложения имеют префикс, соответсвующий имени веб-приложения, их содержащего. Например, бин <code>app-core.cuba:type=CachingFacade</code> загружен веб-приложением <structname>app-core</structname>, реализующим блок Middleware, а бин <code>app.cuba:type=CachingFacade</code> загружен веб-приложением <structname>app</structname>, реализующим блок Web Client.</para>
|
||||
<para>Консоль JMX может также работать с JMX объектами произвольной удаленной JVM. Это актуально в случае развертывания блоков приложения на нескольких экземплярах веб-контейнера, например отдельно Web Client и Middleware. </para>
|
||||
<para>Для подключения к удаленной JVM необходимо в поле <guilabel>Соединение JMX</guilabel> консоли выбрать созданное ранее соединение, либо вызвать экран создания нового соединения:</para>
|
||||
<figure>
|
||||
<title>Редактирование JMX соединения</title>
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata contentwidth="100%" align="center" fileref="img/jmx-connection-edit.png"/>
|
||||
</imageobject>
|
||||
</mediaobject>
|
||||
</figure>
|
||||
<para>Для соединения указывается JMX хост и порт, логин и пароль. Имеется также поле <guilabel>Имя узла</guilabel>, которое заполняется автоматически, если по указанному адресу обнаружен какой-либо блок CUBA-приложения. В этом случае значением этого поля становится комбинация свойств <property>
|
||||
<link linkend="cuba.webHostName">cuba.webHostName</link>
|
||||
</property> и <property>
|
||||
<link linkend="cuba.webPort">cuba.webPort</link>
|
||||
</property> данного блока, что позволяет идентифицировать содержащий его сервер. Если подключение произведено к постороннему JMX интерфейсу, то поле <guilabel>Имя узла</guilabel> будет иметь значение "Unknown JMX interface". Значение данного поля можно произвольно изменять. </para>
|
||||
<para>Для подключения удаленной JVM она должна быть соответствующим образом настроена - см. ниже.</para>
|
||||
</section>
|
||||
<section>
|
||||
<title>Настройка удаленного доступа к JMX</title>
|
||||
<para>В данном разделе рассматривается настройка запуска сервера <application>Tomcat</application>, необходимая для удаленного подключения к нему инструментов JMX.</para>
|
||||
<section>
|
||||
<title>Tomcat JMX под Windows</title>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>Отредактировать файл <filename>bin/setenv.bat</filename> следующим образом:<programlisting>set CATALINA_OPTS=%CATALINA_OPTS% ^
|
||||
-Dcom.sun.management.jmxremote ^
|
||||
-Djava.rmi.server.hostname=192.168.10.10 ^
|
||||
-Dcom.sun.management.jmxremote.ssl=false ^
|
||||
-Dcom.sun.management.jmxremote.port=7777 ^
|
||||
-Dcom.sun.management.jmxremote.authenticate=true ^
|
||||
-Dcom.sun.management.jmxremote.password.file=../conf/jmxremote.password ^
|
||||
-Dcom.sun.management.jmxremote.access.file=../conf/jmxremote.access</programlisting></para>
|
||||
<para>Здесь в параметре <code>java.rmi.server.hostname</code> необходимо указать реальный IP адрес или DNS имя компьютера, на котором запущен сервер, в параметре <code>com.sun.management.jmxremote.port</code> - порт для подключения инструментов JMX.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Отредактировать файл <filename>conf/jmxremote.access</filename>. Он должен содержать имена пользователей, которые будут подключаться к JMX, и их уровень доступа. Например:<programlisting>admin readwrite</programlisting></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Отредактировать файл <filename>conf/jmxremote.password</filename>. Он должен содержать пароли пользователей JMX, например:<programlisting>admin admin</programlisting></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Файл паролей должен иметь разрешение на чтение только для пользователя, от имени которого работает сервер <application>Tomcat</application>. Настроить права можно следующим образом:<itemizedlist>
|
||||
<listitem>
|
||||
<para>Открыть командную строку и перейти в каталог <filename>conf</filename>.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Выполнить команду:</para>
|
||||
<para><prompt>cacls jmxremote.password /P "domain_name\user_name":R</prompt>
|
||||
|
||||
</para>
|
||||
<para>где <code>domain_name\user_name</code> - домен и имя пользователя.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>После выполнения данной команды файл в <application>Проводнике</application> будет отмечен изображением замка.</para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Если <application>Tomcat</application> установлен как служба Windows, то для службы должен быть задан вход в систему с учетной записью, имеющей права на файл <filename>jmxremote.password</filename>. Кроме того, следует иметь в виду, что в этом случае файл <filename>bin/setenv.bat</filename> не используется, и соответствующие параметры запуска JVM должны быть заданы в приложении, настраивающем службу.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
<section>
|
||||
<title>Tomcat JMX под Linux</title>
|
||||
<para><itemizedlist>
|
||||
<listitem>
|
||||
<para>Отредактировать файл <filename>bin/setenv.sh</filename> следующим образом:<programlisting>CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote \
|
||||
-Djava.rmi.server.hostname=192.168.10.10 \
|
||||
-Dcom.sun.management.jmxremote.port=7777 \
|
||||
-Dcom.sun.management.jmxremote.ssl=false \
|
||||
-Dcom.sun.management.jmxremote.authenticate=true"
|
||||
|
||||
CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote.password.file=../conf/jmxremote.password -Dcom.sun.management.jmxremote.access.file=../conf/jmxremote.access"</programlisting></para>
|
||||
<para>Здесь в параметре <code>java.rmi.server.hostname</code> необходимо указать реальный IP адрес или DNS имя компьютера, на котором запущен сервер, в параметре <code>com.sun.management.jmxremote.port</code> - порт для подключения инструментов JMX.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Отредактировать файл <filename>conf/jmxremote.access</filename>. Он должен содержать имена пользователей, которые будут подключаться к JMX, и их уровень доступа. Например:<programlisting>admin readwrite</programlisting></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Отредактировать файл <filename>conf/jmxremote.password</filename>. Он должен содержать пароли пользователей JMX, например:<programlisting>admin admin</programlisting></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Файл паролей должен иметь разрешение на чтение только для пользователя, от имени которого работает сервер <application>Tomcat</application>. Настроить права для текущего пользователя можно следующим образом:<itemizedlist>
|
||||
<listitem>
|
||||
<para>Открыть командную строку и перейти в каталог <filename>conf</filename>.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Выполнить команду:</para>
|
||||
<para><prompt>chmod go-rwx jmxremote.password</prompt>
|
||||
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
<title>Отказоустойчивость и балансировка нагрузки</title>
|
||||
<section id="serverId">
|
||||
<title>Server Id</title>
|
||||
<para><firstterm>Server Id</firstterm> служит для надежной идентификации серверов в кластере Middleware. Идентификатор имеет вид <literal>host:port/context</literal>, например:<programlisting>tezis.haulmont.com:80/app-core</programlisting><programlisting>192.168.44.55:8080/app-core</programlisting></para>
|
||||
<para>Идентификатор формируется на основе параметров конфигурации <link linkend="cuba.webHostName">
|
||||
<property>cuba.webHostName</property>
|
||||
</link>, <link linkend="cuba.webPort">
|
||||
<property>cuba.webPort</property>
|
||||
</link>, <link linkend="cuba.webContextName">
|
||||
<property>cuba.webContextName</property>
|
||||
</link>, поэтому крайне важно корректно указать эти параметры для блока Middleware, работающего в кластере. </para>
|
||||
<para>Server Id может быть получен c помощью бина <code>ServerInfoAPI</code> или через JMX-интерфейс <code>
|
||||
<link linkend="serverInfoMBean">ServerInfoMBean</link>
|
||||
</code>.</para>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []>
|
||||
<!-- This document was created with Syntext Serna Free. --><chapter id="chapter_deployment" lang="ru">
|
||||
<title>Развертывание приложений</title>
|
||||
<para>На диаграмме ниже приведена возможная структура развернутого приложения, созданного на базе платформы. </para>
|
||||
<figure>
|
||||
<title>Структура CUBA-приложения</title>
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata contentwidth="80%" align="center" fileref="img/DeploymentStructure.png"/>
|
||||
</imageobject>
|
||||
</mediaobject>
|
||||
</figure>
|
||||
<para>В приведенном варианте приложение обеспечивает отсутствие единой точки отказа, балансировку нагрузки и подключение различных типов клиентов. Однако в простейшем случае серверная часть приложения может быть развернута на одном компьютере, содержащем, в том числе, и базу данных. </para>
|
||||
<section>
|
||||
<title>Каталоги приложения</title>
|
||||
<para>В данном разделе описываются каталоги файловой системы, используемые различными <link linkend="app_tiers">блоками приложения</link> во время выполнения.</para>
|
||||
<section id="conf_dir">
|
||||
<title>Конфигурационный каталог</title>
|
||||
<para>Каталог конфигурации предназначен для размещения ресурсов, дополняющих и переопределяющих свойства приложения, пользовательский интерфейс и бизнес-логику после развертывания приложения. Переопределение обеспечивается механизмом загрузки интерфейса инфраструктуры <code>
|
||||
<link linkend="resources">Resources</link>
|
||||
</code>, который сначала выполняет поиск в конфигурационном каталоге, а потом в CLASSPATH, так что одноименные ресурсы в конфигурационном каталоге имеют приоритет над расположенными в JAR-файлах и каталогах классов.</para>
|
||||
<para>Конфигурационный каталог может содержать следующие типы ресурсов:<itemizedlist>
|
||||
<listitem>
|
||||
<para>Файл <filename>
|
||||
<link linkend="app_properties_files">local.app.properties</link>
|
||||
</filename>, определяющий параметры развертывания блоков приложения, работающих под управлением веб-сервера</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Конфигурационные файлы <filename>
|
||||
<link linkend="metadata.xml">metadata.xml</link>
|
||||
</filename>, <filename>
|
||||
<link linkend="persistence.xml">persistence.xml</link>
|
||||
</filename>, <filename>
|
||||
<link linkend="remoting-spring.xml">remoting-spring.xml</link>
|
||||
</filename>, <filename>
|
||||
<link linkend="spring.xml">spring.xml</link>
|
||||
</filename>, <filename>
|
||||
<link linkend="views.xml">views.xml</link>
|
||||
</filename></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><link linkend="screen_xml">XML-дескрипторы</link> экранов UI</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><link linkend="screen_controller">Контроллеры</link> экранов UI в виде исходных текстов Java или Groovy</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Скрипты или классы Groovy, а также исходные тексты классов Java, используемые приложением через интерфейс <code>
|
||||
<link linkend="scripting">Scripting</link>
|
||||
</code>.</para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
<para>Расположение конфигурационного каталога определяется свойством приложения <property>
|
||||
<link linkend="cuba.confDir">cuba.confDir</link>
|
||||
</property>. Для блоков Middleware, Web Client и Web Portal в стандартном варианте развертывания в <application>Tomcat</application> это подкаталог с именем веб-приложения в каталоге <filename>tomcat/conf</filename>.</para>
|
||||
</section>
|
||||
<section id="work_dir">
|
||||
<title>Рабочий каталог</title>
|
||||
<para>Рабочий каталог используется приложением для хранения файлов данных и конфигурации.</para>
|
||||
<para>Например, подкаталог <filename>filestorage</filename> рабочего каталога по умолчанию используется <link linkend="file_storage">хранилищем загруженных файлов</link>. Кроме того, блок Middleware на старте сохраняет в рабочем каталоге сгенерированные файлы <filename>
|
||||
<link linkend="persistence.xml">persistence.xml</link>
|
||||
</filename> и <filename>orm.xml</filename>.</para>
|
||||
<para>Расположение рабочего каталога определяется свойством приложения <property>
|
||||
<link linkend="cuba.dataDir">cuba.dataDir</link>
|
||||
</property>. Для блоков Middleware, Web Client и Web Portal в стандартном варианте развертывания в <application>Tomcat</application> это подкаталог с именем веб-приложения в каталоге <filename>tomcat/work</filename>.</para>
|
||||
</section>
|
||||
<section id="log_dir">
|
||||
<title>Каталог журналов</title>
|
||||
<para>В каталоге журналов создаются лог-файлы приложения.</para>
|
||||
<para>Состав и настройка файлов журналов определяются конфигурацией фреймворка <application>Apache log4j</application>. Расположение файла конфигурации определяется системным свойством <literal>
|
||||
<link linkend="log4j.configuration">log4j.configuration</link>
|
||||
</literal>.</para>
|
||||
<para>Данный каталог может быть также использован для сохранения произвольной информации о выполнении приложения. Путь к каталогу журналов определяется свойством приложения <property>
|
||||
<link linkend="cuba.logDir">cuba.logDir</link>
|
||||
</property>. Для блоков Middleware, Web Client и Web Portal в стандартном варианте развертывания в <application>Tomcat</application> это каталог <filename>tomcat/logs</filename>.</para>
|
||||
</section>
|
||||
<section id="temp_dir">
|
||||
<title>Временный каталог</title>
|
||||
<para>Данный каталог может быть использован для создания произвольных временных файлов во время выполнения приложения. Путь к временному каталогу определяется свойством приложения <property>
|
||||
<link linkend="cuba.tempDir">cuba.tempDir</link>
|
||||
</property>. Для блоков Middleware, Web Client и Web Portal в стандартном варианте развертывания в <application>Tomcat</application> это подкаталог с именем веб-приложения в каталоге <filename>tomcat/temp</filename>.</para>
|
||||
</section>
|
||||
<section id="db_dir">
|
||||
<title>Каталог скриптов базы данных</title>
|
||||
<para>В данном каталоге развернутого блока Middleware хранится набор SQL скриптов создания и обновления БД.</para>
|
||||
<para>Структура каталога скриптов повторяет описанную в <xref linkend="db_scripts"/>, но имеет один дополнительный верхний уровень, разделяющий скрипты используемых <link linkend="base_projects">базовых проектов</link> и самого приложения. Нумерация каталогов верхнего уровня определяется во время сборки проекта.</para>
|
||||
<para>Расположение рабочего каталога определяется свойством приложения <property>
|
||||
<link linkend="cuba.dbDir">cuba.dbDir</link>
|
||||
</property>. В стандартном варианте развертывания в <application>Tomcat</application> это подкаталог <filename>WEB-INF/db</filename> каталога веб-приложения среднего слоя, например, <filename>tomcat/webapps/app-core/WEB-INF/db</filename>.</para>
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
<title>Использование инструментов JMX</title>
|
||||
<section>
|
||||
<title>Встроенная JMX консоль</title>
|
||||
<para>Модуль Web Client базового проекта <structname>cuba</structname> платформы содержит средство просмотра и редактирования JMX объектов. Точкой входа в этот инструмент является экран <filename>com/haulmont/cuba/web/app/ui/jmxcontrol/browse/display-mbeans.xml</filename>, зарегистрированный под идентификатором <code>jmxcontrol$DisplayMbeans</code> и в стандартном меню доступный через пункт <guimenu>Администрирование</guimenu> -> <guimenuitem>Консоль JMX</guimenuitem>.</para>
|
||||
<para>Без дополнительной настройки консоль отображает все JMX объекты, зарегистрированные в JVM, на которой работает блок Web Client, к которому в данный момент подключен пользователь. Соответственно, в простейшем случае развертывания всех блоков приложения в одном экземпляре веб-контейнера консоль имеет доступ к JMX бинам всех уровней, а также к JMX объектам самой JVM и веб-контейнера. </para>
|
||||
<para>Имена бинов приложения имеют префикс, соответствующий имени веб-приложения, их содержащего. Например, бин <code>app-core.cuba:type=CachingFacade</code> загружен веб-приложением <structname>app-core</structname>, реализующим блок Middleware, а бин <code>app.cuba:type=CachingFacade</code> загружен веб-приложением <structname>app</structname>, реализующим блок Web Client.</para>
|
||||
<para>Консоль JMX может также работать с JMX объектами произвольной удаленной JVM. Это актуально в случае развертывания блоков приложения на нескольких экземплярах веб-контейнера, например, отдельно Web Client и Middleware. </para>
|
||||
<para>Для подключения к удаленной JVM необходимо в поле <guilabel>Соединение JMX</guilabel> консоли выбрать созданное ранее соединение, либо вызвать экран создания нового соединения:</para>
|
||||
<figure>
|
||||
<title>Редактирование JMX соединения</title>
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata contentwidth="100%" align="center" fileref="img/jmx-connection-edit.png"/>
|
||||
</imageobject>
|
||||
</mediaobject>
|
||||
</figure>
|
||||
<para>Для соединения указывается JMX хост и порт, логин и пароль. Имеется также поле <guilabel>Имя узла</guilabel>, которое заполняется автоматически, если по указанному адресу обнаружен какой-либо блок CUBA-приложения. В этом случае значением этого поля становится комбинация свойств <property>
|
||||
<link linkend="cuba.webHostName">cuba.webHostName</link>
|
||||
</property> и <property>
|
||||
<link linkend="cuba.webPort">cuba.webPort</link>
|
||||
</property> данного блока, что позволяет идентифицировать содержащий его сервер. Если подключение произведено к постороннему JMX интерфейсу, то поле <guilabel>Имя узла</guilabel> будет иметь значение "Unknown JMX interface". Значение данного поля можно произвольно изменять. </para>
|
||||
<para>Для подключения удаленной JVM она должна быть соответствующим образом настроена - см. ниже.</para>
|
||||
</section>
|
||||
<section>
|
||||
<title>Настройка удаленного доступа к JMX</title>
|
||||
<para>В данном разделе рассматривается настройка запуска сервера <application>Tomcat</application>, необходимая для удаленного подключения к нему инструментов JMX.</para>
|
||||
<section>
|
||||
<title>Tomcat JMX под Windows</title>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>Отредактировать файл <filename>bin/setenv.bat</filename> следующим образом:<programlisting>set CATALINA_OPTS=%CATALINA_OPTS% ^
|
||||
-Dcom.sun.management.jmxremote ^
|
||||
-Djava.rmi.server.hostname=192.168.10.10 ^
|
||||
-Dcom.sun.management.jmxremote.ssl=false ^
|
||||
-Dcom.sun.management.jmxremote.port=7777 ^
|
||||
-Dcom.sun.management.jmxremote.authenticate=true ^
|
||||
-Dcom.sun.management.jmxremote.password.file=../conf/jmxremote.password ^
|
||||
-Dcom.sun.management.jmxremote.access.file=../conf/jmxremote.access</programlisting></para>
|
||||
<para>Здесь в параметре <code>java.rmi.server.hostname</code> необходимо указать реальный IP адрес или DNS имя компьютера, на котором запущен сервер, в параметре <code>com.sun.management.jmxremote.port</code> - порт для подключения инструментов JMX.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Отредактировать файл <filename>conf/jmxremote.access</filename>. Он должен содержать имена пользователей, которые будут подключаться к JMX, и их уровень доступа. Например:<programlisting>admin readwrite</programlisting></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Отредактировать файл <filename>conf/jmxremote.password</filename>. Он должен содержать пароли пользователей JMX, например:<programlisting>admin admin</programlisting></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Файл паролей должен иметь разрешение на чтение только для пользователя, от имени которого работает сервер <application>Tomcat</application>. Настроить права можно следующим образом:<itemizedlist>
|
||||
<listitem>
|
||||
<para>Открыть командную строку и перейти в каталог <filename>conf</filename>.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Выполнить команду:</para>
|
||||
<para><prompt>cacls jmxremote.password /P "domain_name\user_name":R</prompt>
|
||||
|
||||
</para>
|
||||
<para>где <code>domain_name\user_name</code> - домен и имя пользователя.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>После выполнения данной команды файл в <application>Проводнике</application> будет отмечен изображением замка.</para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Если <application>Tomcat</application> установлен как служба Windows, то для службы должен быть задан вход в систему с учетной записью, имеющей права на файл <filename>jmxremote.password</filename>. Кроме того, следует иметь в виду, что в этом случае файл <filename>bin/setenv.bat</filename> не используется, и соответствующие параметры запуска JVM должны быть заданы в приложении, настраивающем службу.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
<section>
|
||||
<title>Tomcat JMX под Linux</title>
|
||||
<para><itemizedlist>
|
||||
<listitem>
|
||||
<para>Отредактировать файл <filename>bin/setenv.sh</filename> следующим образом:<programlisting>CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote \
|
||||
-Djava.rmi.server.hostname=192.168.10.10 \
|
||||
-Dcom.sun.management.jmxremote.port=7777 \
|
||||
-Dcom.sun.management.jmxremote.ssl=false \
|
||||
-Dcom.sun.management.jmxremote.authenticate=true"
|
||||
|
||||
CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote.password.file=../conf/jmxremote.password -Dcom.sun.management.jmxremote.access.file=../conf/jmxremote.access"</programlisting></para>
|
||||
<para>Здесь в параметре <code>java.rmi.server.hostname</code> необходимо указать реальный IP адрес или DNS имя компьютера, на котором запущен сервер, в параметре <code>com.sun.management.jmxremote.port</code> - порт для подключения инструментов JMX.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Отредактировать файл <filename>conf/jmxremote.access</filename>. Он должен содержать имена пользователей, которые будут подключаться к JMX, и их уровень доступа. Например:<programlisting>admin readwrite</programlisting></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Отредактировать файл <filename>conf/jmxremote.password</filename>. Он должен содержать пароли пользователей JMX, например:<programlisting>admin admin</programlisting></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Файл паролей должен иметь разрешение на чтение только для пользователя, от имени которого работает сервер <application>Tomcat</application>. Настроить права для текущего пользователя можно следующим образом:<itemizedlist>
|
||||
<listitem>
|
||||
<para>Открыть командную строку и перейти в каталог <filename>conf</filename>.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Выполнить команду:</para>
|
||||
<para><prompt>chmod go-rwx jmxremote.password</prompt>
|
||||
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
<title>Отказоустойчивость и балансировка нагрузки</title>
|
||||
<section id="serverId">
|
||||
<title>Server Id</title>
|
||||
<para><firstterm>Server Id</firstterm> служит для надежной идентификации серверов в кластере Middleware. Идентификатор имеет вид <literal>host:port/context</literal>, например:<programlisting>tezis.haulmont.com:80/app-core</programlisting><programlisting>192.168.44.55:8080/app-core</programlisting></para>
|
||||
<para>Идентификатор формируется на основе параметров конфигурации <link linkend="cuba.webHostName">
|
||||
<property>cuba.webHostName</property>
|
||||
</link>, <link linkend="cuba.webPort">
|
||||
<property>cuba.webPort</property>
|
||||
</link>, <link linkend="cuba.webContextName">
|
||||
<property>cuba.webContextName</property>
|
||||
</link>, поэтому крайне важно корректно указать эти параметры для блока Middleware, работающего в кластере. </para>
|
||||
<para>Server Id может быть получен c помощью бина <code>ServerInfoAPI</code> или через JMX-интерфейс <code>
|
||||
<link linkend="serverInfoMBean">ServerInfoMBean</link>
|
||||
</code>.</para>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -44,7 +44,7 @@
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>Обязательным блоком любого приложения является средний слой - <structname>Middleware</structname>. Для реализации пользовательского интерфейса как правило используется один или несколько клиентских блоков, например <structname>Web Client</structname> и <structname>Web Portal</structname>. </para>
|
||||
<para>Обязательным блоком любого приложения является средний слой - <structname>Middleware</structname>. Для реализации пользовательского интерфейса, как правило, используется один или несколько клиентских блоков, например, <structname>Web Client</structname> и <structname>Web Portal</structname>. </para>
|
||||
<para>Вышеперечисленные блоки являются стандартными, однако в комплексном приложении для разделения функциональности можно без труда создать произвольное количество как клиентских блоков, так и блоков среднего слоя.</para>
|
||||
<para>Все клиентские блоки взаимодействуют со средним слоем одинаковым образом посредством протокола <application>HTTP</application>, что позволяет размещать средний слой произвольным образом, в том числе за сетевым экраном. Следует отметить, что при развертывании в простейшем случае среднего слоя и веб-клиента на одном сервере между ними организуется локальное взаимодействие в обход сетевого стека для снижения накладных расходов.</para>
|
||||
</section>
|
||||
@ -337,7 +337,7 @@
|
||||
</term>
|
||||
<listitem>
|
||||
<para>Определяет встраиваемую сущность, экземпляры которой хранятся вместе с владеющей сущностью в той же таблице. </para>
|
||||
<para>Для задания имени сущности тебуется применение аннотации <link linkend="metaclass_annotation">
|
||||
<para>Для задания имени сущности требуется применение аннотации <link linkend="metaclass_annotation">
|
||||
<code>@MetaClass</code>
|
||||
</link>.</para>
|
||||
</listitem>
|
||||
@ -451,7 +451,7 @@
|
||||
<code>@SystemLevel</code>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>Указывает, что данная сущность является системной и не должна быть доступна для выбора пользователем в различных списках сущностей, например как тип параметра универсального фильтра или тип <link linkend="runtime_properties">динамического атрибута</link>. </para>
|
||||
<para>Указывает, что данная сущность является системной и не должна быть доступна для выбора пользователем в различных списках сущностей, например, как тип параметра универсального фильтра или тип <link linkend="runtime_properties">динамического атрибута</link>. </para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
@ -520,10 +520,10 @@
|
||||
<para><code>name</code> - имя колонки</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><code>length</code> - (необязательный параметр, по умолчанию <literal>255</literal>) - длина колонки. Используется также при формировании <link linkend="metadata_framework">метаданных</link> и в конечном счете может ограничивать максимальныю длину вводимого текста в визуальных компонентах, работающих с данным атрибутом.</para>
|
||||
<para><code>length</code> - (необязательный параметр, по умолчанию <literal>255</literal>) - длина колонки. Используется также при формировании <link linkend="metadata_framework">метаданных</link> и, в конечном счете, может ограничивать максимальную длину вводимого текста в визуальных компонентах, работающих с данным атрибутом.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><code>nullable</code> - (необязательный параметр, по умолчанию <code>true</code>) - может ли атрибут содержать <code>null</code>. При указании <code>nullable = false</code> <glossterm linkend="jpa">JPA</glossterm> контролирует наличие значения поля при сохранении, кроме того, визуальные компоненты, работающих с данным атрибутом, могут сигнализировать пользователю о необходимости ввода значения.</para>
|
||||
<para><code>nullable</code> - (необязательный параметр, по умолчанию <code>true</code>) - может ли атрибут содержать <code>null</code>. При указании <code>nullable = false</code> <glossterm linkend="jpa">JPA</glossterm> контролирует наличие значения поля при сохранении, кроме того, визуальные компоненты, работающие с данным атрибутом, могут сигнализировать пользователю о необходимости ввода значения.</para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
</listitem>
|
||||
@ -541,7 +541,7 @@
|
||||
<para><code>fetch</code> - (по умолчанию <code>EAGER</code>) параметр, определяющий, будет ли JPA <glossterm linkend="eager_fetching">энергично</glossterm> загружать ассоциированную сущность. Данный параметр всегда должен быть установлен в значение <code>LAZY</code>, так как в CUBA-приложении политика загрузки связей определяется динамически на основе механизма <link linkend="views">представлений</link>.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><code>optional</code> - (необязательный параметр, по умолчанию <code>true</code>) - может ли атрибут содержать <code>null</code>. При указании <code>optional = false</code> <glossterm linkend="jpa">JPA</glossterm> контролирует наличие ссылки при сохранении, кроме того, визуальные компоненты, работающих с данным атрибутом, могут сигнализировать пользователю о необходимости ввода значения.</para>
|
||||
<para><code>optional</code> - (необязательный параметр, по умолчанию <code>true</code>) - может ли атрибут содержать <code>null</code>. При указании <code>optional = false</code> <glossterm linkend="jpa">JPA</glossterm> контролирует наличие ссылки при сохранении, кроме того, визуальные компоненты, работающие с данным атрибутом, могут сигнализировать пользователю о необходимости ввода значения.</para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
<para>Например, несколько экземпляров <code>Order</code> (заказов) ссылаются на один экземпляр <code>Customer</code> (покупателя), в этом случае класс <code>Order</code> должен содержать следующее объявление:<programlisting>@ManyToOne(fetch = FetchType.LAZY)
|
||||
@ -609,7 +609,7 @@ protected Driver driver;</programlisting></para>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>Определяет атрибут-коллекцию ссылок на сущность с типом ассоциации много-ко-многим.</para>
|
||||
<para>Ассоциация много-ко-многим всегда имеет ведущую сторону и может иметь обратную сторону - ведомую. На ведущей строне указывается дополнительная аннотация <code>@JoinTable</code>, на ведомой стороне - параметр <code>mappedBy</code>.</para>
|
||||
<para>Ассоциация много-ко-многим всегда имеет ведущую сторону и может иметь обратную сторону - ведомую. На ведущей стороне указывается дополнительная аннотация <code>@JoinTable</code>, на ведомой стороне - параметр <code>mappedBy</code>.</para>
|
||||
<para>Параметры:<itemizedlist>
|
||||
<listitem>
|
||||
<para><code>mappedBy</code> - поле связанной сущности, определяющее ассоциацию с ведущей стороны. Необходимо указывать только на ведомой стороне.</para>
|
||||
@ -742,7 +742,7 @@ private Integer version;</programlisting></para>
|
||||
<para>Данная аннотация не обязательна для полей, снабженных следующими аннотациями пакета <code>javax.persistence</code>: <code>@Column</code>, <code>@OneToOne</code>, <code>@OneToMany</code>, <code>@ManyToOne</code>, <code>@ManyToMany</code>, <code>@Embedded</code>. Такие поля отражаются в метаданных автоматически. Поэтому <code>@MetaProperty</code> в основном применяется для определения неперсистентных атрибутов сущностей. </para>
|
||||
<para>Параметры:<itemizedlist>
|
||||
<listitem>
|
||||
<para><code>mandatory</code> - (необязательный параметр, по умолчанию <code>false</code>) - может ли атрибут содержать <code>null</code>. При указании <code>mandatory = true</code> визуальные компоненты, работающих с данным атрибутом, могут сигнализировать пользователю о необходимости ввода значения.</para>
|
||||
<para><code>mandatory</code> - (необязательный параметр, по умолчанию <code>false</code>) - может ли атрибут содержать <code>null</code>. При указании <code>mandatory = true</code> визуальные компоненты, работающие с данным атрибутом, могут сигнализировать пользователю о необходимости ввода значения.</para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
<para>Пример использования для поля:<programlisting>@Transient
|
||||
@ -787,7 +787,7 @@ private Driver driver;</programlisting></para>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>Указывает на то, что связь является композицией - более тесным вариантом ассоциации. Это означает, что связанная сущность имеет смысл только как часть владеющей сущности, т.е. создается и удаляется вместе с ней. </para>
|
||||
<para>Например список пунктов в заказе (класс <code>Order</code> содержит коллекцию экземпляров <code>Item</code>):<programlisting>@OneToMany(mappedBy = "order")
|
||||
<para>Например, список пунктов в заказе (класс <code>Order</code> содержит коллекцию экземпляров <code>Item</code>):<programlisting>@OneToMany(mappedBy = "order")
|
||||
@Composition
|
||||
protected List<Item> items;</programlisting></para>
|
||||
<para>Указание для связи аннотации <code>@Composition</code> позволяет организовать в <link linkend="screen_edit">экранах редактирования</link> специальный <link linkend="datasource_commitMode">режим коммита</link> источников данных, при котором изменения экземпляров детализирующей сущности сохраняются в базе данных только при коммите основной сущности.</para>
|
||||
@ -801,7 +801,7 @@ protected List<Item> items;</programlisting></para>
|
||||
<para>Служит для описания способа получения локализованного значения некоторого изменяющегося атрибута, которое возвращает метод <code><link linkend="messageTools">MessageTools</link>.getLocValue()</code>. </para>
|
||||
<para>Параметры:<itemizedlist>
|
||||
<listitem>
|
||||
<para><code>messagePack</code> - явное указание пакета, из которого будет взято локализованное сообщение, например <code>com.haulmont.cuba.core.entity</code></para>
|
||||
<para><code>messagePack</code> - явное указание пакета, из которого будет взято локализованное сообщение, например, <code>com.haulmont.cuba.core.entity</code></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><code>messagePackExpr</code> - выражение в терминах пути к атрибуту, хранящему имя пакета, из которого будет взято локализованное сообщение, например <code>proc.messagesPack</code>. Путь начинается с атрибута текущей сущности. </para>
|
||||
@ -873,12 +873,12 @@ public class Customer extends StandardEntity {
|
||||
}</programlisting></para>
|
||||
<para>Для правильного отражения в <link linkend="metadata_framework">метаданных</link> класс перечисления, используемый в качестве типа атрибута сущности, должен реализовывать интерфейс <code>EnumClass</code>.</para>
|
||||
<para>Как видно из примеров, для атрибута <code>grade</code> в БД хранится значение типа <code>Integer</code>, задаваемое полем <code>id</code> перечисления <code>CustomerGrade</code>, а конкретно <literal>10</literal>, <literal>20</literal> или <literal>30</literal>. В то же время прикладной код и метаданные работают с самим типом <code>CustomerGrade</code> через методы доступа, которые и осуществляют конвертацию.</para>
|
||||
<para>При наличии в поле БД значения, не соответствующего ни одному значению перечисления, метод <code>getGrade()</code> просто вернет <code>null</code>. Для ввода нового значения, например <code>HIGHER</code>, между <code>HIGH</code> и <code>PREMIUM</code>, достаточно добавить это значение в перечисление с идентификатором <literal>15</literal>, при этом сортировка по полю <code>Customer.grade</code> останется верной.</para>
|
||||
<para>При наличии в поле БД значения, не соответствующего ни одному значению перечисления, метод <code>getGrade()</code> просто вернет <code>null</code>. Для ввода нового значения, например, <code>HIGHER</code>, между <code>HIGH</code> и <code>PREMIUM</code>, достаточно добавить это значение в перечисление с идентификатором <literal>15</literal>, при этом сортировка по полю <code>Customer.grade</code> останется верной.</para>
|
||||
</section>
|
||||
<section id="soft_deletion">
|
||||
<title>Мягкое удаление</title>
|
||||
<para>Платформа <productname>CUBA</productname> поддерживает режим "мягкого удаления" данных - когда вместо удаления записей из базы данных они только помечаются определенным образом и становятся недоступными для обычного использования. В дальнейшем такие записи можно либо совсем удалить из БД с помощью отдельной регламентной процедуры, либо восстановить.</para>
|
||||
<para>Механизм мягкого удаления является "прозрачным" для прикладного программиста - достаточно убедиться что класс сущности реализует интерфейс <code>SoftDelete</code>, и платформа сама нужным образом будет модифицировать запросы и операции с данными.</para>
|
||||
<para>Механизм мягкого удаления является "прозрачным" для прикладного программиста - достаточно убедиться, что класс сущности реализует интерфейс <code>SoftDelete</code>, и платформа сама нужным образом будет модифицировать запросы и операции с данными.</para>
|
||||
<para>Режим мягкого удаления имеет следующие преимущества:<itemizedlist>
|
||||
<listitem>
|
||||
<para>значительно снижается риск потери данных вследствие неверных действий пользователей</para>
|
||||
@ -892,7 +892,7 @@ public class Customer extends StandardEntity {
|
||||
<para>Отрицательной стороной мягкого удаления является увеличение объема базы данных и потенциальная необходимость дополнительных процедур ее очистки.</para>
|
||||
<section>
|
||||
<title>Использование</title>
|
||||
<para>Для того, чтобы экземпляры сущности удалялись мягко, класс сущности должен реализовывать интерфейс <code>SoftDelete</code>, а соответствующая таблица БД должна содержать колонки: <itemizedlist>
|
||||
<para>Для того чтобы экземпляры сущности удалялись мягко, класс сущности должен реализовывать интерфейс <code>SoftDelete</code>, а соответствующая таблица БД должна содержать колонки: <itemizedlist>
|
||||
<listitem>
|
||||
<para><database>DELETE_TS</database> - когда удалена запись</para>
|
||||
</listitem>
|
||||
@ -980,10 +980,10 @@ protected Role role;</programlisting></para>
|
||||
<para>В режиме мягкого удаления для ограничения уникальности некоторого значения необходимо обеспечить существование единственной неудаленной записи с этим значением, и произвольного количества удаленных записей с этим же значением.</para>
|
||||
<para>Реализуется данная логика путем, специфичным для используемого сервера базы данных:<itemizedlist>
|
||||
<listitem>
|
||||
<para>Если сервер БД поддерживает частичные (partial) индексы (например <application>PostgreSQL</application>), то ограничение уникальности можно создать следующим образом:<programlisting>create unique index IDX_SEC_USER_UNIQ_LOGIN on SEC_USER (LOGIN_LC) where DELETE_TS is null</programlisting></para>
|
||||
<para>Если сервер БД поддерживает частичные (partial) индексы (например, <application>PostgreSQL</application>), то ограничение уникальности можно создать следующим образом:<programlisting>create unique index IDX_SEC_USER_UNIQ_LOGIN on SEC_USER (LOGIN_LC) where DELETE_TS is null</programlisting></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Если сервер БД не поддерживает частичные индексы (например <application>Microsoft SQL Server 2005</application>), то в уникальный индекс можно включить поле <database>DELETE_TS</database>:<programlisting>create unique index IDX_SEC_USER_UNIQ_LOGIN on SEC_USER (LOGIN_LC, DELETE_TS)</programlisting></para>
|
||||
<para>Если сервер БД не поддерживает частичные индексы (например, <application>Microsoft SQL Server 2005</application>), то в уникальный индекс можно включить поле <database>DELETE_TS</database>:<programlisting>create unique index IDX_SEC_USER_UNIQ_LOGIN on SEC_USER (LOGIN_LC, DELETE_TS)</programlisting></para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
</section>
|
||||
@ -1001,7 +1001,7 @@ protected Role role;</programlisting></para>
|
||||
<para>Метод <code>onBeforeDetach()</code> вызывается перед отделением объекта от <code>
|
||||
<link linkend="entityManager">EntityManager</link>
|
||||
</code> при коммите транзакции.</para>
|
||||
<para>Данный слушатель можно использовать например для заполнения неперсистентных атрибутов сущности перед отправкой ее на клиентский уровень.</para>
|
||||
<para>Данный слушатель можно использовать, например, для заполнения неперсистентных атрибутов сущности перед отправкой ее на клиентский уровень.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
@ -1094,9 +1094,9 @@ public class MyBean implements AppContext.Listener {
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
<para>Для всех экземпляров некоторого класса сущности создается и кэшируется <emphasis>один</emphasis> экземпляр слушателя определенного типа, поэтому слушатель <emphasis>не должен иметь состояния</emphasis>.</para>
|
||||
<para>Если для сущности объявлены несколько слушателей одного типа (например аннотациями класса сущности и его предков, плюс динамически), то их вызов будет выполняться в следующем порядке:<orderedlist>
|
||||
<para>Если для сущности объявлены несколько слушателей одного типа (например, аннотациями класса сущности и его предков, плюс динамически), то их вызов будет выполняться в следующем порядке:<orderedlist>
|
||||
<listitem>
|
||||
<para>Для каждого предка начиная с самого дальнего вызываются его динамически добавленные слушатели, затем статически назначенные.</para>
|
||||
<para>Для каждого предка, начиная с самого дальнего, вызываются его динамически добавленные слушатели, затем статически назначенные.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>После всех предков вызываются динамически добавленные слушатели данного класса, затем статически назначенные.</para>
|
||||
@ -1285,7 +1285,7 @@ assert groupNameProp.getDomain().getName().equals("sec$Group");</progr
|
||||
<para><code>asClass()</code> - возвращает <link linkend="metaClass">мета-класс</link> ассоциированной сущности для ссылочного атрибута</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><code>isOrdered()</code> – возвращает <code>true</code> если атрибут представляет собой упорядоченную коллекцию (например <code>List</code>)</para>
|
||||
<para><code>isOrdered()</code> – возвращает <code>true</code> если атрибут представляет собой упорядоченную коллекцию (например, <code>List</code>)</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><code>getCardinality()</code> – вид отношения для ссылочного атрибута: <code>ONE_TO_ONE</code>, <code>MANY_TO_ONE</code>, <code>ONE_TO_MANY</code>, <code>MANY_TO_MANY</code></para>
|
||||
@ -1323,7 +1323,7 @@ assert groupNameProp.getDomain().getName().equals("sec$Group");</progr
|
||||
<title>Внимание</title>
|
||||
<para>Текущая реализация сборки метаданных имеет следующие ограничения:<itemizedlist>
|
||||
<listitem>
|
||||
<para>Классы сущностей должны размещаться в пакетах, имеющих не менее 3-х уровней иерархии, например <code>com.abc.sales</code>, <code>com.abc.sales.entity</code></para>
|
||||
<para>Классы сущностей должны размещаться в пакетах, имеющих не менее 3-х уровней иерархии, например, <code>com.abc.sales</code>, <code>com.abc.sales.entity</code></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Персистентные сущности не могут ссылаться на неперсистентные. Обратное возможно, т.е. неперсистентная сущность может иметь атрибут типа некоторой персистентной сущности.</para>
|
||||
@ -1356,7 +1356,7 @@ assert groupNameProp.getDomain().getName().equals("sec$Group");</progr
|
||||
</itemizedlist></para>
|
||||
<para><code>Datatype</code> сопоставляется атрибуту сущности на старте системы по следующим правилам:<itemizedlist>
|
||||
<listitem>
|
||||
<para>Если для поля или метода задана аннотация <code>@MetaProperty</code> с непустым значением <code>datatype</code>, то атрибуту соспоставляется экземпляр <code>Datatype</code> с данным именем. </para>
|
||||
<para>Если для поля или метода задана аннотация <code>@MetaProperty</code> с непустым значением <code>datatype</code>, то атрибуту сопоставляется экземпляр <code>Datatype</code> с данным именем. </para>
|
||||
<para>Например, при следующем объявлении атрибута сущности он получит нестандартный тип <code>GeoCoordinateDatatype</code> (см. пример ниже):<programlisting>@MetaProperty(datatype = GeoCoordinateDatatype.NAME)
|
||||
@Column(name = "LATITUDE")
|
||||
private Double latitude;</programlisting></para>
|
||||
@ -1378,7 +1378,7 @@ private Double latitude;</programlisting></para>
|
||||
<para><code>parse()</code> - преобразовывает строку в значение нужного типа </para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
<para><code>Datatype</code> определяет два набора методов для форматирования/парсинга: с учетом локали и без учета локали. Преобразование с учетом локали используется повсеместно в пользовательском интерфейсе, преобразование без учета локали используется в системных механизмах, например для сериализации в <link linkend="rest_api">REST API</link>. </para>
|
||||
<para><code>Datatype</code> определяет два набора методов для форматирования/парсинга: с учетом локали и без учета локали. Преобразование с учетом локали используется повсеместно в пользовательском интерфейсе, преобразование без учета локали используется в системных механизмах, например, для сериализации в <link linkend="rest_api">REST API</link>. </para>
|
||||
<para>Форматы для преобразований без учета локали задаются в вышеупомянутом файле <filename>
|
||||
<link linkend="datatypes.xml">datatypes.xml</link>
|
||||
</filename>.</para>
|
||||
@ -1544,7 +1544,7 @@ private Double latitude;</programlisting></para>
|
||||
<title>Общие сведения</title>
|
||||
<para>При извлечении сущностей из базы данных обычно встает вопрос - как обеспечить загрузку связанных сущностей на нужную глубину? </para>
|
||||
<para>Например, для браузера Заказов нужно отобразить дату и сумму заказа совместно с названием Покупателя, т.е. загрузить связанный экземпляр Покупателя. А для экрана редактирования Заказа необходимо загрузить еще и коллекцию Пунктов заказа, причем каждый Пункт заказа должен содержать связанный экземпляр Товара для отображения его наименования. </para>
|
||||
<para><link linkend="lazy_loading">Загрузка по требованию</link> в большинстве случаев не может помочь, так как обработка данных как правило происходит не в транзакции, в которой загружаются сущности, а, например, на клиентском <link linkend="app_tiers">уровне</link> в пользовательском интерфейсе. В то же время задание <glossterm linkend="eager_fetching">энергичной загрузки</glossterm> в <link linkend="entity_annotations">аннотациях сущностей</link> недопустимо, так как приводит к постоянному извлечению всего графа связанных сущностей, который может быть очень большим.</para>
|
||||
<para><link linkend="lazy_loading">Загрузка по требованию</link> в большинстве случаев не может помочь, так как обработка данных, как правило, происходит не в транзакции, в которой загружаются сущности, а, например, на клиентском <link linkend="app_tiers">уровне</link> в пользовательском интерфейсе. В то же время задание <glossterm linkend="eager_fetching">энергичной загрузки</glossterm> в <link linkend="entity_annotations">аннотациях сущностей</link> недопустимо, так как приводит к постоянному извлечению всего графа связанных сущностей, который может быть очень большим.</para>
|
||||
<para>Другой похожей проблемой является ограничение набора <glossterm linkend="local_attribute">локальных</glossterm> атрибутов сущностей загружаемого графа: например, некоторая сущность имеет 50 атрибутов, в том числе BLOB, а в экране отображается только 10 атрибутов. Зачем загружать из БД, затем сериализовать и передавать клиенту 40 атрибутов, которые ему в данный момент не нужны?</para>
|
||||
<para>Механизм <firstterm>представлений</firstterm> (views) решает эти проблемы, обеспечивая извлечение из базы данных и передачу клиенту графов сущностей, ограниченных в глубину и по атрибутам. <firstterm>Представление</firstterm> является описателем графа объектов, который требуется в некотором экране UI или другом процессе обработки данных.</para>
|
||||
<para>Обработка представлений производится следующим образом:<itemizedlist>
|
||||
@ -1664,7 +1664,7 @@ private Double latitude;</programlisting></para>
|
||||
</property> блока <structname>Middleware</structname>, т.е. в файле <filename>{имя_проекта}-app.properties</filename> модуля <structname>core</structname>. Это обеспечит автоматическое развертывание представлений на старте приложения в репозитории <structname>Middleware</structname> (см. метод <code>AbstractViewRepository.init()</code>). Развернутые представления будут доступны и для <structname>Middleware</structname>, и для клиентских <link linkend="app_tiers">блоков</link>, которые получат соответствующие экземпляры <code>View</code> при подключении к среднему слою.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Если существуют представления, которые необходимы только какому-то одному клиентскому блоку приложения, то можно определить их в аналогичном файле этого блока, например <filename>{имя_проекта}-web-views.xml</filename>, и зарегистрировать в свойстве <property>
|
||||
<para>Если существуют представления, которые необходимы только какому-то одному клиентскому блоку приложения, то можно определить их в аналогичном файле этого блока, например, <filename>{имя_проекта}-web-views.xml</filename>, и зарегистрировать в свойстве <property>
|
||||
<link linkend="cuba.viewsConfig">cuba.viewsConfig</link>
|
||||
</property> этого блока, т.е. в данном случае в файле <filename>{имя_проекта}-web-app.properties</filename>. Тогда клиентский блок сначала загрузит все имеющиеся представления с <structname>Middleware</structname>, а затем развернет свои собственные (см. <code>ViewRepositoryClientImpl.init()</code>).</para>
|
||||
<para>Возможна также ситуация, когда некоторому клиентскому блоку не нужны глобальные представления, зарегистрированные на среднем слое, или нужны редко. В этом случае имеет смысл объявить в этом клиентском блоке свойство <link linkend="cuba.lazyLoadServerViews">
|
||||
@ -1672,7 +1672,7 @@ private Double latitude;</programlisting></para>
|
||||
</link>, тогда глобальные представления будут загружаться на клиентский уровень не все сразу, а по необходимости.</para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
<para>Если на момент развертывания некоторого представления в репозитории уже есть представление для этого же класса сущности и с таким же именем, то новое будет проигнорировано. Для того, чтобы представление заменило имеющееся в репозитории и гарантированно было развернуто, в XML-описателе должен быть явно указан атрибут <literal>overwrite = "true"</literal>. В частности, развертывание представлений клиентского уровня производится после загрузки представлений со среднего слоя, поэтому некоторое клиентское представление может оказаться "замаскированным" одноименным представлением <structname>Middleware</structname>.</para>
|
||||
<para>Если на момент развертывания некоторого представления в репозитории уже есть представление для этого же класса сущности и с таким же именем, то новое будет проигнорировано. Для того чтобы представление заменило имеющееся в репозитории и гарантированно было развернуто, в XML-описателе должен быть явно указан атрибут <literal>overwrite = "true"</literal>. В частности, развертывание представлений клиентского уровня производится после загрузки представлений со среднего слоя, поэтому некоторое клиентское представление может оказаться "замаскированным" одноименным представлением <structname>Middleware</structname>.</para>
|
||||
<tip>
|
||||
<para>Рекомендуется давать представлениям "описательные" имена. Например, не "browse", а "customerBrowse". Это упрощает поиск XML-описателей представлений по имени в процессе разработки приложения.</para>
|
||||
</tip>
|
||||
@ -1680,7 +1680,7 @@ private Double latitude;</programlisting></para>
|
||||
</section>
|
||||
<section id="infrastructure_interfaces">
|
||||
<title>Интерфейсы инфраструктуры</title>
|
||||
<para>Интерфейсы инфраструктуры обеспечивают доступ к часто используемой функциональности платформы. Большинство из этих интерфейсов расположены в <link linkend="app_modules">модуле</link> <structname>global</structname> и могут быть использованы как на среднем слое, так и в <link linkend="app_tiers">блоках</link> клиентского уровня, но некоторые (например <code>
|
||||
<para>Интерфейсы инфраструктуры обеспечивают доступ к часто используемой функциональности платформы. Большинство из этих интерфейсов расположены в <link linkend="app_modules">модуле</link> <structname>global</structname> и могут быть использованы как на среднем слое, так и в <link linkend="app_tiers">блоках</link> клиентского уровня, но некоторые (например, <code>
|
||||
<link linkend="persistence">Persistence</link>
|
||||
</code>) доступны только коду среднего слоя.</para>
|
||||
<para>Интерфейсы инфраструктуры реализуются бинами <application>Spring Framework</application>, поэтому они могут быть инжектированы в любые другие управляемые компоненты (<link linkend="managed_beans">Managed Beans</link>, <link linkend="services">сервисы среднего слоя</link>, <link linkend="screen_controller">контроллеры</link> экранов универсального пользовательского интерфейса.</para>
|
||||
@ -1930,7 +1930,7 @@ BigDecimal amount = scripting.runGroovyScript("com/abc/sales/CalculatePrice
|
||||
<para>нельзя изменять тип исходного текста с Groovy на Java</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>если существовал исходный текст Groovy, и был однажды скомпилирован, то удаление файла исходного текста не приведет к загрузке другого класса из classpath - будет по прежнему возвращаться класс, скомпилированный из удаленного исходника.</para>
|
||||
<para>если существовал исходный текст Groovy, и был однажды скомпилирован, то удаление файла исходного текста не приведет к загрузке другого класса из classpath - будет по-прежнему возвращаться класс, скомпилированный из удаленного исходника.</para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
<para>Пример:<programlisting>@Inject
|
||||
@ -1979,7 +1979,7 @@ Date date = timeSource.currentTimestamp();</programlisting><programlisting>long
|
||||
<para><code>ThreadLocal</code> переменная, хранящая экземпляры <code>SecurityContext</code></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Коллекция слушателей жизненного цикла приложения ( <code>AppContext.Listener</code>)</para>
|
||||
<para>Коллекция слушателей жизненного цикла приложения (<code>AppContext.Listener</code>)</para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
<para><code>AppContext</code> инициализируется на запуске приложения классами-загрузчиками, специфичными для типа <link linkend="app_tiers">блока</link> приложения:<itemizedlist>
|
||||
@ -2011,7 +2011,7 @@ Date date = timeSource.currentTimestamp();</programlisting><programlisting>long
|
||||
});</programlisting> </para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Проверки того, что данный <link linkend="app_tiers">блок</link> приложения полностью инициализирован и готов к выполнению. Такая проверка обычно необходима в методах бинов, автоматически запускаемых <link linkend="scheduled_tasks_spring">планировщиком</link> <application>Sping</application>.</para>
|
||||
<para>Проверки того, что данный <link linkend="app_tiers">блок</link> приложения полностью инициализирован и готов к выполнению. Такая проверка обычно необходима в методах бинов, автоматически запускаемых <link linkend="scheduled_tasks_spring">планировщиком</link> <application>Spring</application>.</para>
|
||||
<para>Пример:<programlisting>if (!AppContext.isStarted())
|
||||
return;</programlisting></para>
|
||||
</listitem>
|
||||
@ -2093,7 +2093,7 @@ classpath:app.properties
|
||||
file:${catalina.home}/conf/app-core/local.app.properties</programlisting>
|
||||
<para>Здесь префикс <literal>classpath:</literal> означает, что данный файл нужно искать в Java classpath, префикс <literal>file:</literal> − в файловой системе. Возможно использование системных свойств Java, в данном случае это <literal>catalina.home</literal> − путь к корню <application>Tomcat</application>.</para>
|
||||
<para>Порядок перечисления файлов важен, так как значения, указанные в каждом последующем файле заменяют значения одноименных свойств, заданные в предыдущих файлах. Этим достигается переопределение свойств платформы в конкретном приложении.</para>
|
||||
<para>Последний файл в приведенном наборе − <filename>local.app.properties</filename>. Он может использоваться для переопределения свойств приложения при развертывании. Если этого файла нет, он игнорируется. Если же во время инсталляции системы требуется переопределение некоторых параметров (как правило различных URL), достаточно создать этот файл и поместить в него переопределяемые свойства. При последующих обновлениях системы такой файл с локальными настройками легко сохранить.</para>
|
||||
<para>Последний файл в приведенном наборе − <filename>local.app.properties</filename>. Он может использоваться для переопределения свойств приложения при развертывании. Если этого файла нет, он игнорируется. Если же во время инсталляции системы требуется переопределение некоторых параметров (как правило, различных URL), достаточно создать этот файл и поместить в него переопределяемые свойства. При последующих обновлениях системы такой файл с локальными настройками легко сохранить.</para>
|
||||
<para>Аналогом <filename>local.app.properties</filename> для <structname>Desktop Client</structname> служат аргументы командной строки запуска JVM. Загрузчик свойств данного блока воспринимает все аргументы, содержащие знак "<literal>=</literal>", как пары ключ-значение, и заменяет ими соответствующие свойства приложения, заданные в файлах <filename>app.properties</filename>.</para>
|
||||
<tip>
|
||||
<para>Правила задания информации в файлах <filename>*.properties</filename>:</para>
|
||||
@ -2142,7 +2142,7 @@ file:${catalina.home}/conf/app-core/local.app.properties</programlisting>
|
||||
</code> методом <code>clearCache()</code> или <code>
|
||||
<link linkend="cachingFacadeMBean">CachingFacadeMBean</link>
|
||||
</code> методом <code>clearConfigStorageCache()</code>.</para>
|
||||
<para>Следует иметь в виду, что на клиентском уровне чтение свойства, хранящегося в БД, приводит к запросу к <structname>Middleware</structname>, что менее эффективно, чем чтение локального свойства из <filename>app.properties</filename>. Для уменьшения количества таких запросов клиент кэширует все свойства, хранящиеся в БД, на время жизни экземпляра реализации конфигурационного интерфейса. Поэтому если например в некотором экране UI необходимо несколько раз обратиться к свойствам одного конфигурационного интерфейса, лучше получить ссылку на него при инициализации экрана, и сохранить в поле для последующих обращений к одному и тому же экземпляру. </para>
|
||||
<para>Следует иметь в виду, что на клиентском уровне чтение свойства, хранящегося в БД, приводит к запросу к <structname>Middleware</structname>, что менее эффективно, чем чтение локального свойства из <filename>app.properties</filename>. Для уменьшения количества таких запросов клиент кэширует все свойства, хранящиеся в БД, на время жизни экземпляра реализации конфигурационного интерфейса. Поэтому если ,например, в некотором экране UI необходимо несколько раз обратиться к свойствам одного конфигурационного интерфейса, лучше получить ссылку на него при инициализации экрана, и сохранить в поле для последующих обращений к одному и тому же экземпляру. </para>
|
||||
</section>
|
||||
<section id="config_interfaces">
|
||||
<title>Конфигурационные интерфейсы</title>
|
||||
@ -2259,15 +2259,15 @@ Role getAdminRole();</programlisting></para>
|
||||
<title>Локализация сообщений</title>
|
||||
<para>Приложение на основе платформы CUBA поддерживает локализацию сообщений, то есть вывод всех элементов пользовательского интерфейса на языке, выбранном пользователем.</para>
|
||||
<para>Возможности выбора языка определяются комбинацией свойств приложения <link linkend="cuba.localeSelectVisible">cuba.localeSelectVisible</link> и <link linkend="cuba.availableLocales">cuba.availableLocales</link>.</para>
|
||||
<para>Для того, чтобы некоторое сообщение могло быть локализовано, т.е. представлено пользователю на нужном языке, его необходимо поместить в так называемый <firstterm>пакет сообщений</firstterm>. </para>
|
||||
<para>Для того чтобы некоторое сообщение могло быть локализовано, т.е. представлено пользователю на нужном языке, его необходимо поместить в так называемый <firstterm>пакет сообщений</firstterm>. </para>
|
||||
<section id="message_packs">
|
||||
<title>Пакеты сообщений</title>
|
||||
<para>Пакет сообщений представляет собой набор файлов свойств с именами вида <filename>messages{_XX}.properties</filename>, расположенных в одном Java-пакете. Суффикс <literal>XX</literal> определяет язык, для которого в данном файле содержатся сообщения, и соответствует коду языка в <code>Locale.getLanguage()</code>. Возможно также использование остальных атрибутов <code>Locale</code>, например <code>country</code>. В этом случая файл пакета будет иметь вид <filename>messages{_XX_YY}.properties</filename>. Один из файлов пакета может быть без суффикса языка - это <firstterm>файл по умолчанию</firstterm>. Именем пакета сообщений считается имя Java-пакета, в котором расположены файлы пакета.</para>
|
||||
<para>Пакет сообщений представляет собой набор файлов свойств с именами вида <filename>messages{_XX}.properties</filename>, расположенных в одном Java-пакете. Суффикс <literal>XX</literal> определяет язык, для которого в данном файле содержатся сообщения, и соответствует коду языка в <code>Locale.getLanguage()</code>. Возможно также использование остальных атрибутов <code>Locale</code>, например, <code>country</code>. В этом случая файл пакета будет иметь вид <filename>messages{_XX_YY}.properties</filename>. Один из файлов пакета может быть без суффикса языка - это <firstterm>файл по умолчанию</firstterm>. Именем пакета сообщений считается имя Java-пакета, в котором расположены файлы пакета.</para>
|
||||
<para>Рассмотрим пример:<programlisting>/com/abc/sales/gui/customer/messages.properties
|
||||
/com/abc/sales/gui/customer/messages_fr.properties
|
||||
/com/abc/sales/gui/customer/messages_ru.properties</programlisting></para>
|
||||
<para>Данный пакет состоит из 3-х файлов - один для русского языка, один для французского, и один по умолчанию. Имя пакета - <code>com.abc.sales.gui.customer</code> </para>
|
||||
<para>Файлы сообщений содержат пары ключ-значение, где ключ - это идентификатор сообщения, на который ссылается код приложения, а значение - само сообщение на языке данного файла. Правила задания пар аналогичны правилам файлов свойств<code>java.util.Properties</code>, со следующими особенностями:<itemizedlist>
|
||||
<para>Файлы сообщений содержат пары ключ-значение, где ключ - это идентификатор сообщения, на который ссылается код приложения, а значение - само сообщение на языке данного файла. Правила задания пар аналогичны правилам файлов свойств <code>java.util.Properties</code>, со следующими особенностями:<itemizedlist>
|
||||
<listitem>
|
||||
<para>Кодировка файла - обязательно <code>UTF-8</code></para>
|
||||
</listitem>
|
||||
@ -2298,7 +2298,7 @@ someMessage=Some Message
|
||||
</itemizedlist></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Если в конфигурационном каталоге сообщение не найдено, производится поиск в classpath по такому-же алгоритму.</para>
|
||||
<para>Если в конфигурационном каталоге сообщение не найдено, производится поиск в classpath по такому же алгоритму.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>На клиентском <link linkend="app_tiers">уровне</link>, если сообщение не найдено на предыдущих шагах, отправляется запрос на <structname>Middleware</structname>, и сообщение ищется там аналогичным способом.</para>
|
||||
@ -2320,10 +2320,10 @@ someMessage=Some Message
|
||||
</section>
|
||||
<section id="main_message_pack">
|
||||
<title>Главный пакет сообщений</title>
|
||||
<para>Каждый стандартный <link linkend="app_tiers">блок</link> приложения определяет для себя один <firstterm>главный</firstterm> пакет сообщений. Для блоков клиентского уровня этот пакет содержит названия пунктов главного меню и общих элементов UI (например названия кнопок <guibutton>OK</guibutton> и <guibutton>Cancel</guibutton>). Для всех блоков приложения, включая <structname>Midleware</structname>, главный пакет определяет форматы преобразований <link linkend="datatype">
|
||||
<para>Каждый стандартный <link linkend="app_tiers">блок</link> приложения определяет для себя один <firstterm>главный</firstterm> пакет сообщений. Для блоков клиентского уровня этот пакет содержит названия пунктов главного меню и общих элементов UI (например, названия кнопок <guibutton>OK</guibutton> и <guibutton>Cancel</guibutton>). Для всех блоков приложения, включая <structname>Middleware</structname>, главный пакет определяет форматы преобразований <link linkend="datatype">
|
||||
<code>Datatype</code>
|
||||
</link>.</para>
|
||||
<para>Для указания главного пакета соощений используется свойство приложения <property>
|
||||
<para>Для указания главного пакета сообщений используется свойство приложения <property>
|
||||
<link linkend="cuba.mainMessagePack">cuba.mainMessagePack</link>
|
||||
</property>. Значением свойства может быть либо один пакет, либо список пакетов, разделенный пробелами. Например:<programlisting>cuba.mainMessagePack=com.haulmont.cuba.web com.abc.sales.web</programlisting></para>
|
||||
<para>В данном случае сообщения, заданные во втором пакете списка будут перекрывать сообщений из первого пакета. Таким образом в проекте приложения можно переопределять сообщения, заданные в пакетах <link linkend="base_projects">базовых проектов</link>.</para>
|
||||
@ -2346,7 +2346,7 @@ Order=Заказ
|
||||
Order.customer=Покупатель
|
||||
Order.date=Дата
|
||||
Order.amount=Сумма</programlisting></para>
|
||||
<para>Такие пакеты сообщений как правило используются неявно для разработчика, например визуальными компонентами <code>
|
||||
<para>Такие пакеты сообщений, как правило, используются неявно для разработчика, например, визуальными компонентами <code>
|
||||
<link linkend="gui_Table">Table</link>
|
||||
</code> и <code>
|
||||
<link linkend="gui_FieldGroup">FieldGroup</link>
|
||||
@ -2357,7 +2357,7 @@ Order.amount=Сумма</programlisting></para>
|
||||
</code> <code>getEntityCaption()</code>, <code>getPropertyCaption()</code></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>в XML дескрипторе экрана - указанием ссылки на сообщение по правилам <code>MessageTools.<link linkend="messageTools.loadString">loadString</link>()</code>: <literal>msg://{entity_package}/{key}</literal>, например <programlisting>caption="msg://com.abc.sales.entity/Customer.name"</programlisting></para>
|
||||
<para>в XML дескрипторе экрана - указанием ссылки на сообщение по правилам <code>MessageTools.<link linkend="messageTools.loadString">loadString</link>()</code>: <literal>msg://{entity_package}/{key}</literal>, например, <programlisting>caption="msg://com.abc.sales.entity/Customer.name"</programlisting></para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
</section>
|
||||
@ -2378,7 +2378,7 @@ public enum CustomerGrade { PREMIUM, HIGH, STANDARD }</programlisting></para>
|
||||
CustomerGrade.PREMIUM=Премиум
|
||||
CustomerGrade.HIGH=Высокий
|
||||
CustomerGrade.STANDARD=Стандартный</programlisting></para>
|
||||
<para>Локализованные значения перечислений автоматически используются различными визуальными компонентами, например <code>
|
||||
<para>Локализованные значения перечислений автоматически используются различными визуальными компонентами, например, <code>
|
||||
<link linkend="gui_LookupField">LookupField</link>
|
||||
</code>. Для программного получения локализованного значения перечисления можно использовать метод <code>getMessage()</code> интерфейса <code>
|
||||
<link linkend="messages">Messages</link>
|
||||
@ -2393,7 +2393,7 @@ CustomerGrade.STANDARD=Стандартный</programlisting></para>
|
||||
<para>Основной элемент подсистемы контроля доступа в CUBA-приложении - пользовательская сессия. Это объект класса <code>UserSession</code>, который ассоциирован с аутентифицированным в данный момент в системе пользователем, и содержит информацию о правах доступа пользователя к данным. Объект текущей сессии может быть получен в любом <link linkend="app_tiers">блоке</link> приложения через интерфейс инфраструктуры <code>
|
||||
<link linkend="userSessionSource">UserSessionSource</link>
|
||||
</code>. </para>
|
||||
<para>Пользовательская сессия создается на <structname>Middleware</structname> при выполнении метода <code>LoginService.login()</code> после аутентификации пользователя по переданному имени и паролю. Объект <code>UserSession</code> затем кэшируется в данном блоке <structname>Middleware</structname>, и возвращается на клиентский уровень. При работе в кластере объект сессии реплицируется на соседние узлы кластера <structname>Middleware</structname>. Клиентский блок, получив объект сессии, также сохраняет его у себя, так или иначе ассоциируя с активным пользователем (например в HTTP сессии). Далее все вызовы <structname>Middleware</structname> для данного пользователя сопровождаются передачей идентификатора сессии (типа <code>UUID</code>), причем прикладному коду не нужно об этом заботиться - идентификатор сессии передается автоматически, независимо от сигнатуры вызываемых методов среднего слоя. Обработка вызовов клиентов на <structname>Middleware</structname> начинается с извлечения из кэша сессии по полученному идентификатору и установки ее в потоке выполнения. Объект сессии удаляется из кэша при вызове метода <code>LoginService.logout()</code>, либо при истечения времени бездействия, определяемого свойством приложения <property>
|
||||
<para>Пользовательская сессия создается на <structname>Middleware</structname> при выполнении метода <code>LoginService.login()</code> после аутентификации пользователя по переданному имени и паролю. Объект <code>UserSession</code> затем кэшируется в данном блоке <structname>Middleware</structname>, и возвращается на клиентский уровень. При работе в кластере объект сессии реплицируется на соседние узлы кластера <structname>Middleware</structname>. Клиентский блок, получив объект сессии, также сохраняет его у себя, так или иначе ассоциируя с активным пользователем (например, в HTTP сессии). Далее все вызовы <structname>Middleware</structname> для данного пользователя сопровождаются передачей идентификатора сессии (типа <code>UUID</code>), причем прикладному коду не нужно об этом заботиться - идентификатор сессии передается автоматически, независимо от сигнатуры вызываемых методов среднего слоя. Обработка вызовов клиентов на <structname>Middleware</structname> начинается с извлечения из кэша сессии по полученному идентификатору и установки ее в потоке выполнения. Объект сессии удаляется из кэша при вызове метода <code>LoginService.logout()</code>, либо при истечении времени бездействия, определяемого свойством приложения <property>
|
||||
<link linkend="cuba.userSessionExpirationTimeoutSec">cuba.userSessionExpirationTimeoutSec</link>
|
||||
</property>.</para>
|
||||
<para>Таким образом, идентификатор сессии, создаваемой при входе пользователя в систему, служит для аутентификации пользователя при каждом вызове среднего слоя.</para>
|
||||
@ -2406,7 +2406,7 @@ CustomerGrade.STANDARD=Стандартный</programlisting></para>
|
||||
<para><code>userLogin</code> - логин текущего зарегистрированного или замещенного пользователя в нижнем регистре.</para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
<para>Атрибуты реплицируются в кластере Middleware так же как и все остальные данные сессии.</para>
|
||||
<para>Атрибуты реплицируются в кластере Middleware так же, как и все остальные данные сессии.</para>
|
||||
</section>
|
||||
<section id="login">
|
||||
<title>Вход в систему</title>
|
||||
@ -2489,12 +2489,12 @@ executor.submit(new Runnable() {
|
||||
</section>
|
||||
<section>
|
||||
<title>Передача исключений Middleware</title>
|
||||
<para>Если при выполнении запроса от клиента на Middleware возникает исключение, выполнение прерывается и на клиента возвращается объект исключения, как правило включающий цепочку порождающих друг друга исключений. Так как цепочка исключений может содержать классы, недоступные клиентскому блоку (например, исключения JDBC-драйвера), на клиента передается не сама эта цепочка, а ее представление внутри специального создаваемого исключения <code>RemoteException</code>. </para>
|
||||
<para>Если при выполнении запроса от клиента на Middleware возникает исключение, выполнение прерывается и на клиента возвращается объект исключения, как правило, включающий цепочку порождающих друг друга исключений. Так как цепочка исключений может содержать классы, недоступные клиентскому блоку (например, исключения JDBC-драйвера), на клиента передается не сама эта цепочка, а ее представление внутри специального создаваемого исключения <code>RemoteException</code>. </para>
|
||||
<para>Информация об исключениях-причинах сохраняется в виде списка объектов <code>RemoteException.Cause</code>. Каждый объект <code>Cause</code> хранит обязательно имя класса исключения и его сообщение. Кроме того, если класс исключения "поддерживается клиентом", то <code>Cause</code> содержит также и сам объект исключения. Это дает возможность передать на клиента информацию в полях исключения. </para>
|
||||
<para>Класс исключения, объекты которого нужно передавать на клиентский уровень именно в виде Java-объектов, нужно аннотировать <code>@SupportedByClient</code>, например: <programlisting>@SupportedByClient
|
||||
public class WorkflowException extends RuntimeException {
|
||||
...</programlisting></para>
|
||||
<para>Таким образом, при возникновении на Middleware исключения, не аннотированного <code>@SupportedByClient</code>, вызывающий клиентский код получит <code>RemoteException</code>, внутри которого будет находится исходное исключение в виде строки. Если же исходное исключение аннотировано <code>@SupportedByClient</code>, то вызывающий код получит именно его. Это дает возможность в прикладном коде организовывать обработку декларируемых <link linkend="services">сервисами</link> Middleware исключений традиционным образом - с помощью блоков <code>try...catch</code>.</para>
|
||||
<para>Таким образом, при возникновении на Middleware исключения, не аннотированного <code>@SupportedByClient</code>, вызывающий клиентский код получит <code>RemoteException</code>, внутри которого будет находиться исходное исключение в виде строки. Если же исходное исключение аннотировано <code>@SupportedByClient</code>, то вызывающий код получит именно его. Это дает возможность в прикладном коде организовывать обработку декларируемых <link linkend="services">сервисами</link> Middleware исключений традиционным образом - с помощью блоков <code>try...catch</code>.</para>
|
||||
<para>Упаковку объектов исключений в <code>RemoteException</code> перед передачей на клиентский уровень выполняет перехватчик вызовов <link linkend="services">сервисов</link> - класс <code>ServiceInterceptor</code>. Кроме того, он же выполняет логгирование исключений. По умолчанию в журнал выводится вся информация об исключении, включая полный stacktrace. Если это нежелательно, можно добавить классу исключения аннотацию <code>@Logging</code>, указав в ней тип логгирования:<itemizedlist>
|
||||
<listitem>
|
||||
<para><code>FULL</code> - (по умолчанию) полная информация, включая stacktrace</para>
|
||||
@ -2644,7 +2644,7 @@ public class OrderServiceBean implements OrderService {
|
||||
<para>Для того чтобы вызывать сервис, в клиентском блоке приложения для него должен быть создан соответствующий прокси-объект. Делается это путем объявления имени и интерфейса сервиса в параметрах фабрики прокси-объектов. Для блока <structname>Web Client</structname> это бин класса <code>WebRemoteProxyBeanCreator</code>, для <structname>Web Portal</structname> - <code>PortalRemoteProxyBeanCreator</code> , для <structname>Desktop Client</structname> - <code>RemoteProxyBeanCreator</code> .</para>
|
||||
<para>Фабрика прокси-объектов конфигурируется в файле <filename>
|
||||
<link linkend="spring.xml">spring.xml</link>
|
||||
</filename> ссответствующего клиентского блока.</para>
|
||||
</filename> соответствующего клиентского блока.</para>
|
||||
<para>Например, чтобы в приложении <application>sales</application> вызвать с веб-клиента сервис <code>sales_OrderService</code>, необходимо добавить в файл <filename>web-spring.xml</filename> модуля <structname>web</structname> следующее:</para>
|
||||
<programlisting language="xml"><bean id="sales_proxyCreator" class="com.haulmont.cuba.web.sys.remoting.WebRemoteProxyBeanCreator">
|
||||
<property name="clusterInvocationSupport" ref="cuba_clusterInvocationSupport"/>
|
||||
@ -2663,7 +2663,7 @@ orderService.calculateTotals(order);</programlisting></para>
|
||||
</section>
|
||||
<section id="managed_beans">
|
||||
<title>Управляемые бины</title>
|
||||
<para><firstterm>Управляемые бины (Managed Beans)</firstterm> − это программные компоненты, предназначенные для реализации бизнес-логики приложения. Термин "управляемые" в данном случае означает, что созданием экземпляров и установкой связей между такими компонентами управляет <glossterm linkend="container">контейнер</glossterm>, который является основной частью фреймворка <application>Sping</application>.</para>
|
||||
<para><firstterm>Управляемые бины (Managed Beans)</firstterm> − это программные компоненты, предназначенные для реализации бизнес-логики приложения. Термин "управляемые" в данном случае означает, что созданием экземпляров и установкой связей между такими компонентами управляет <glossterm linkend="container">контейнер</glossterm>, который является основной частью фреймворка <application>Spring</application>.</para>
|
||||
<warning>
|
||||
<para>Managed Bean представляет собой <firstterm>singleton</firstterm>, то есть в некотором блоке приложения существует только один экземпляр данного класса. Поэтому, если бин содержит изменяемые данные в полях (другими словами, имеет состояние), то обращение к таким данным необходимо синхронизировать.</para>
|
||||
</warning>
|
||||
@ -2685,7 +2685,7 @@ public class OrderWorker {
|
||||
<para>Класс управляемого бина должен находиться внутри дерева пакетов с корнем, заданным в элементе <literal>context:component-scan</literal> файла <filename>
|
||||
<link linkend="spring.xml">spring.xml</link>
|
||||
</filename>. В нашем случае файл <filename>spring.xml</filename> содержит элемент:<programlisting><context:component-scan base-package="com.sample.sales"/></programlisting>что означает, что поиск аннотированных бинов для данного блока приложения будет происходить начиная с пакета <code>com.sample.sales</code>.</para>
|
||||
<para>Если нужно обеспечить возможность подмены реализации, рекомендуется выделять бизнес-интерфейс бина, например следующим образом:</para>
|
||||
<para>Если нужно обеспечить возможность подмены реализации, рекомендуется выделять бизнес-интерфейс бина, например, следующим образом:</para>
|
||||
<programlisting>package com.sample.sales.core;
|
||||
|
||||
import com.sample.sales.entity.Order;
|
||||
@ -2739,7 +2739,7 @@ public class OrderServiceBean implements OrderService {
|
||||
</section>
|
||||
<section id="jmx_beans">
|
||||
<title>JMX-бины</title>
|
||||
<para>Иногда требуется предоставить администратору системы возможность просматривать и изменять состояние некоторого <link linkend="managed_beans">управляемого бина</link> во время выполнения. В этом случае рекомендуется создать JMX-бин - программный компонент, имеющий <glossterm linkend="jmx">JMX</glossterm>-интерфейс. Такой бин как правило делегирует вызовы управляемому бину, содержащему кэш, конфигурационные данные или статистику, к которым нужно обеспечить доступ через JMX.</para>
|
||||
<para>Иногда требуется предоставить администратору системы возможность просматривать и изменять состояние некоторого <link linkend="managed_beans">управляемого бина</link> во время выполнения. В этом случае рекомендуется создать JMX-бин - программный компонент, имеющий <glossterm linkend="jmx">JMX</glossterm>-интерфейс. Такой бин, как правило, делегирует вызовы управляемому бину, содержащему кэш, конфигурационные данные или статистику, к которым нужно обеспечить доступ через JMX.</para>
|
||||
<figure>
|
||||
<title/>
|
||||
<mediaobject>
|
||||
@ -3035,7 +3035,7 @@ if (persistence.getDbDialect() instanceof PostgresDbDialect)
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><code>getReferenceId()</code> - возвращает идентификатор связанной сущности без загрузки ее из БД. </para>
|
||||
<para>Предположим, в <glossterm linkend="persistence_context">персистентный контекст</glossterm> загружен экземпляр <code>Order</code>, и нужно получить значение идентификатора экземпляра <code>Customer</code>, связанного с данным Заказом. Стандартное решение <code>order.getCustomer().getId()</code> приведет к выполнению SQL запроса к БД для загрузки экземпляра <code>Customer</code>, что в данном случае избыточно, так как значение идентификатора Покупателя физически находится также и в таблице Заказов. Выполнение же <programlisting>persistence.getTools().getReferenceId(order, "customer")</programlisting>не вызывет никаких дополнительных запросов к базе данных. </para>
|
||||
<para>Предположим, в <glossterm linkend="persistence_context">персистентный контекст</glossterm> загружен экземпляр <code>Order</code>, и нужно получить значение идентификатора экземпляра <code>Customer</code>, связанного с данным Заказом. Стандартное решение <code>order.getCustomer().getId()</code> приведет к выполнению SQL запроса к БД для загрузки экземпляра <code>Customer</code>, что в данном случае избыточно, так как значение идентификатора Покупателя физически находится также и в таблице Заказов. Выполнение же <programlisting>persistence.getTools().getReferenceId(order, "customer")</programlisting>не вызовет никаких дополнительных запросов к базе данных. </para>
|
||||
<para>Данный метод работает только для экземпляров в состоянии <link linkend="entity_states">Managed</link>.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
@ -3050,10 +3050,10 @@ tools.foo();</programlisting><programlisting>((MyPersistenceTools) persistence.g
|
||||
<para>Вспомогательный класс для получения информации о персистентных сущностях. В отличие от бинов <code>Persistence</code> и <code>PersistenceTools</code> доступен на всех <link linkend="app_tiers">уровнях</link> приложения.</para>
|
||||
<para>Методы <code>PersistenceHelper</code>:<itemizedlist>
|
||||
<listitem>
|
||||
<para><code>isNew()</code> - определяет, является ли переданный экземпляр только что созданным, т.е. находящимся в состоянии <link linkend="entity_states">New</link>. Возвращает <code>true</code> также если экземпляр не является персистентной сущностью.</para>
|
||||
<para><code>isNew()</code> - определяет, является ли переданный экземпляр только что созданным, т.е. находящимся в состоянии <link linkend="entity_states">New</link>. Возвращает <code>true</code>, также если экземпляр не является персистентной сущностью.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><code>isDetached()</code> - определяет, находится ли переданный экземпляр в состоянии <link linkend="entity_states">Detached</link>. Возвращает <code>true</code> также если экземпляр не является персистентной сущностью.</para>
|
||||
<para><code>isDetached()</code> - определяет, находится ли переданный экземпляр в состоянии <link linkend="entity_states">Detached</link>. Возвращает <code>true</code>, также если экземпляр не является персистентной сущностью.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><code>isSoftDeleted()</code> - определяет, поддерживает ли переданный класс сущности <link linkend="soft_deletion">мягкое удаление</link></para>
|
||||
@ -3222,7 +3222,7 @@ tools.foo();</programlisting><programlisting>((MyPersistenceTools) persistence.g
|
||||
</section>
|
||||
<section id="query">
|
||||
<title>Выполнение JPQL запросов</title>
|
||||
<para>Для выполнения <link linkend="jpql">JPQL</link> запросов предназначен интерфейс <code>Query</code>, ссылку на который который можно получить у текущего экземпляра <code>EntityManager</code> вызовом метода <code>createQuery()</code>. Если запрос предполагается использовать для извлечения сущностей, рекомендуется вызывать <code>createQuery()</code> с передачей типа результата, что приведет к созданию <code>TypedQuery</code>. </para>
|
||||
<para>Для выполнения <link linkend="jpql">JPQL</link> запросов предназначен интерфейс <code>Query</code>, ссылку на который можно получить у текущего экземпляра <code>EntityManager</code> вызовом метода <code>createQuery()</code>. Если запрос предполагается использовать для извлечения сущностей, рекомендуется вызывать <code>createQuery()</code> с передачей типа результата, что приведет к созданию <code>TypedQuery</code>. </para>
|
||||
<para>Методы <code>Query</code> в основном соответствуют методам стандартного интерфейса <ulink url="http://docs.oracle.com/javaee/5/api/javax/persistence/Query.html">
|
||||
<code>javax.persistence.Query</code>
|
||||
</ulink>. Рассмотрим отличия.<itemizedlist>
|
||||
@ -3262,7 +3262,7 @@ assertTrue(user1 == user);</programlisting></para>
|
||||
<para>Такое поведение определяется параметром <code>openjpa.IgnoreChanges=true</code>, заданным в файле <link linkend="persistence.xml">
|
||||
<filename>persistence.xml</filename>
|
||||
</link> базового проекта <structname>cuba</structname>. В прикладном проекте данный параметр можно изменить, указав его в собственном <filename>persistence.xml</filename>.</para>
|
||||
<para>Запросы, модифицирующие данные (<code>update</code>, <code>delete</code>) приводят к сбросу (flush) в базу данных текущего песрсистентного контекста перед выполнением. Другими словами, ORM сначала синхронизирует состояние сущностей в персистентном контексте и в БД, а уже потом выполняет модифицирующий запрос. Рекомендуется выполнять такие запросы в неизмененном персистентном контексте, чтобы исключить неявные действия ORM, которые могут отрицательно сказаться на производительности.</para>
|
||||
<para>Запросы, модифицирующие данные (<code>update</code>, <code>delete</code>) приводят к сбросу (flush) в базу данных текущего персистентного контекста перед выполнением. Другими словами, ORM сначала синхронизирует состояние сущностей в персистентном контексте и в БД, а уже потом выполняет модифицирующий запрос. Рекомендуется выполнять такие запросы в неизмененном персистентном контексте, чтобы исключить неявные действия ORM, которые могут отрицательно сказаться на производительности.</para>
|
||||
<section>
|
||||
<title>Поиск подстроки без учета регистра</title>
|
||||
<para>Для удобного формирования условия поиска без учета регистра символов и по любой части строки можно использовать префикс <literal>(?i)</literal> имени параметра запроса, например:<programlisting>select c from sales$Customer c where c.name like :(?i)name</programlisting></para>
|
||||
@ -3391,7 +3391,7 @@ try {
|
||||
<para>Любой метод <link linkend="managed_beans">управляемого бина</link> <structname>Middleware</structname> можно пометить аннотацией <code>@org.springframework.transaction.annotation.Transactional</code>, что вызовет автоматическое создание транзакции при вызове этого метода. В таком методе не нужно вызывать <code>Persistence.createTransaction()</code>, а можно сразу получать <code>EntityManager</code> и работать с ним.</para>
|
||||
<para>Для аннотации <code>@Transactional</code> можно указать параметры. Основным параметром является режим создания транзакции - <code>Propagation</code>. Значение <code>REQUIRED</code> соответствует <code>getTransaction()</code>, значение <code>REQUIRES_NEW</code> - <code>createTransaction()</code>. По умолчанию <code>REQUIRED</code>.
|
||||
</para>
|
||||
<para>Декларативное управление транзакциями позволяет уменьшить количество <ulink url="http://en.wikipedia.org/wiki/Boilerplate_code">boilerplate кода</ulink>, однако имеет следующий недостаток: коммит транзакции проиходит вне прикладного кода, что часто затрудняет отладку, т.к. скрывается момент отправки изменений в БД и перехода сущностей в состояние <link linkend="entity_states">Detached</link>. Кроме того, следует иметь в виду, что декларативная разметка сработает только в случае вызова метода контейнером, т.е. вызов транзакционного метода из другого метода того же самого объекта не приведет к старту транзакции.
|
||||
<para>Декларативное управление транзакциями позволяет уменьшить количество <ulink url="http://en.wikipedia.org/wiki/Boilerplate_code">boilerplate кода</ulink>, однако имеет следующий недостаток: коммит транзакции происходит вне прикладного кода, что часто затрудняет отладку, т.к. скрывается момент отправки изменений в БД и перехода сущностей в состояние <link linkend="entity_states">Detached</link>. Кроме того, следует иметь в виду, что декларативная разметка сработает только в случае вызова метода контейнером, т.е. вызов транзакционного метода из другого метода того же самого объекта не приведет к старту транзакции.
|
||||
</para>
|
||||
<para>В связи с этим рекомендуется применять декларативное управление транзакциями только для простых случаев типа метода <link linkend="services">сервиса</link>, читающего некоторый объект и возвращающего его на клиента. </para>
|
||||
</section>
|
||||
@ -3522,7 +3522,7 @@ void methodB() {
|
||||
tx.end();
|
||||
}
|
||||
}</programlisting></para>
|
||||
<para>В последнем случае исключение в точке (8) возникнет только если сущность является оптимистично блокируемой, т.е. если она реализует интерфейс <code>Versioned</code>.</para>
|
||||
<para>В последнем случае исключение в точке (8) возникнет, только если сущность является оптимистично блокируемой, т.е. если она реализует интерфейс <code>Versioned</code>.</para>
|
||||
</section>
|
||||
</section>
|
||||
<section id="transaction_timeout">
|
||||
@ -3543,7 +3543,7 @@ public void someServiceMethod() {
|
||||
</property>), выполняется дополнительный оператор в БД: <code>set local statement_timeout to {value}</code>. При этом в случае превышения таймаута запрос будет прерван самим сервером БД. </para>
|
||||
<para>Для снижения нагрузки от этих дополнительных операторов рекомендуется поступать следующим образом: <itemizedlist>
|
||||
<listitem>
|
||||
<para>Таймаут по умолчанию устанавливать не на <structname>Middleware</structname> с помощью свойства <property>cuba.defaultQueryTimeoutSec</property>, в на самом сервере <application>PostgreSQL</application> в файле <filename>postgresql.conf</filename>, например <literal>statement_timeout = 3000</literal> (это в миллисекундах). </para>
|
||||
<para>Таймаут по умолчанию устанавливать не на <structname>Middleware</structname> с помощью свойства <property>cuba.defaultQueryTimeoutSec</property>, а на самом сервере <application>PostgreSQL</application> в файле <filename>postgresql.conf</filename>, например, <literal>statement_timeout = 3000</literal> (это в миллисекундах). </para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Для методов, которым требуется большее время таймаута (отчеты и пр.), явно указывать желаемый таймаут в параметрах транзакции. </para>
|
||||
@ -3557,11 +3557,11 @@ public void someServiceMethod() {
|
||||
<section id="dataService">
|
||||
<title>DataService и DataWorker</title>
|
||||
<para><link linkend="managed_beans">Управляемый бин</link> <code>DataWorker</code> является универсальным средством для загрузки графов сущностей из базы данных, и для сохранения изменений, произведенных в <link linkend="entity_states">Detached</link> экземплярах сущностей. <link linkend="services">Сервис</link> <code>DataService</code> является фасадом для вызова <code>DataWorker</code> с клиентского <link linkend="app_tiers">уровня</link> приложения.</para>
|
||||
<para>Выделение бизнес-логики загрузки и сохранения в <code>DataWorker</code> дает возможность при необходимости создать свой сервис, делегирующий основную работу <code>DataWorker</code> и выполняющий дополнительные преобразования, например перед возвратом данных на клиентский уровень.</para>
|
||||
<para>Выделение бизнес-логики загрузки и сохранения в <code>DataWorker</code> дает возможность при необходимости создать свой сервис, делегирующий основную работу <code>DataWorker</code> и выполняющий дополнительные преобразования, например, перед возвратом данных на клиентский уровень.</para>
|
||||
<para><code>DataWorker</code> всегда стартует новую транзакцию и по завершению работы выполняет коммит, таким образом возвращая сущности в состоянии <link linkend="entity_states">Detached</link>.</para>
|
||||
<para>Методы <code>DataWorker</code>:<itemizedlist>
|
||||
<listitem>
|
||||
<para><code>load()</code>, <code>loadList()</code> - загружает граф сущностей в сответствии с параметрами переданного объекта <code>LoadContext</code>. </para>
|
||||
<para><code>load()</code>, <code>loadList()</code> - загружает граф сущностей в соответствии с параметрами переданного объекта <code>LoadContext</code>. </para>
|
||||
<para>Данные методы проверяют наличие у пользователя права <code>EntityOp.READ</code> на загружаемую сущность. Кроме того, при извлечении сущностей из БД накладываются ограничения групп доступа (см. руководство <productname>Платформа CUBA. Подсистема безопасности</productname>). Для отмены действия ограничений в текущем запросе можно передать в <code>LoadContext</code> атрибут <code>useSecurityConstraints = false</code>.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
@ -3569,7 +3569,7 @@ public void someServiceMethod() {
|
||||
<para>Данный метод проверяет наличие у пользователя права <code>EntityOp.UPDATE</code> на изменяемые сущности, и <code>EntityOp.DELETE</code> на удаляемые. </para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><code>commitNotDetached()</code> - аналогичен методу <code>commit()</code>, но предназначен для сохранения в БД экземпляров, у которых отсутствует информация о <link linkend="entity_states">Detached</link> состоянии. Такие экземпляры сущностей могут быть переданы с клиентов, которые работают не напрямую с объектами, загруженными <structname>Middleware</structname>, а с дополнительными Data Transfer Objects, либо вообще не с Java объектами, а с их XML или JSON представлением (как например клиенты <link linkend="rest_api">REST API</link>)</para>
|
||||
<para><code>commitNotDetached()</code> - аналогичен методу <code>commit()</code>, но предназначен для сохранения в БД экземпляров, у которых отсутствует информация о <link linkend="entity_states">Detached</link> состоянии. Такие экземпляры сущностей могут быть переданы с клиентов, которые работают не напрямую с объектами, загруженными <structname>Middleware</structname>, а с дополнительными Data Transfer Objects, либо вообще не с Java объектами, а с их XML или JSON представлением (как, например, клиенты <link linkend="rest_api">REST API</link>)</para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
<para>В процессе загрузки данных <code>DataWorker</code> может реализовывать дополнительную функциональность, описанную ниже.</para>
|
||||
@ -3583,7 +3583,7 @@ public void someServiceMethod() {
|
||||
<para>на клиентском уровне в источнике данных дубликаты исчезают, т.к. попадают в мэп (<code>java.util.Map</code>) </para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>при постраничном отображении на одной странице оказывается меньшее количество строк чем запрошено, общее количество строк наоборот завышено.</para>
|
||||
<para>при постраничном отображении на одной странице оказывается меньшее количество строк, чем запрошено, общее количество строк наоборот завышено.</para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
<para>Таким образом, рекомендуется в JPQL запросы браузеров включать предложение <literal> distinct</literal>, которое гарантирует отсутствие дубликатов записей при выборке из базы данных. Однако в некоторых серверах БД (в частности <application>PostgreSQL</application>) при большом количестве извлекаемых записей (более 10000) SQL запрос с <literal>distinct</literal> выполняется недопустимо долго.</para>
|
||||
@ -3591,7 +3591,7 @@ public void someServiceMethod() {
|
||||
<link linkend="cuba.inMemoryDistinct">cuba.inMemoryDistinct</link>
|
||||
</property>, при активации которого выполняется следующее: <itemizedlist>
|
||||
<listitem>
|
||||
<para>В JPQL запросе должен по прежнему присутствовать <literal>select distinct</literal></para>
|
||||
<para>В JPQL запросе должен по-прежнему присутствовать <literal>select distinct</literal></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>В <code>DataWorker</code> из JPQL запроса перед отправкой в ORM <literal>distinct</literal> вырезается </para>
|
||||
@ -3652,19 +3652,19 @@ public void someServiceMethod() {
|
||||
<para>Проект CUBA-приложения всегда содержит два набора SQL скриптов:<itemizedlist>
|
||||
<listitem>
|
||||
<para>Скрипты создания БД - предназначены для создания базы данных с нуля.</para>
|
||||
<para>Скрипты создания располагаются в каталоге <filename>/db/init</filename> модуля <structname>core</structname>. Для каждого типа СУБД, поддерживаемой приложением, создается свой набор скриптов и располагается в подкаталоге с именем, соответствующим значению перечисления <code>DbmsType</code>, например <filename>/db/init/postgres</filename>. Имена скриптов создания должны иметь вид <filename>{optional_prefix}create-db.sql</filename>.</para>
|
||||
<para>Скрипты создания располагаются в каталоге <filename>/db/init</filename> модуля <structname>core</structname>. Для каждого типа СУБД, поддерживаемой приложением, создается свой набор скриптов и располагается в подкаталоге с именем, соответствующим значению перечисления <code>DbmsType</code>, например, <filename>/db/init/postgres</filename>. Имена скриптов создания должны иметь вид <filename>{optional_prefix}create-db.sql</filename>.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Скрипты обновления БД - предназначены для поэтапного приведения структуры БД к текущему состоянию <link linkend="data_model">модели данных</link>.</para>
|
||||
<para>Скрипты обновления располагаются в каталоге <filename>/db/update</filename> модуля <structname>core</structname>. Для каждого типа СУБД, поддерживаемой приложением, создается свой набор скриптов и располагается в подкаталоге с именем, соответствующим значению перечисления <code>DbmsType</code>, например <filename>/db/update/postgres</filename>. </para>
|
||||
<para>Скрипты обновления должны иметь имена, которые при сортировке в алфавитном порядке образуют правильную последовательность их выполнения (обычно это хронологическая последовательность их создания). Поэтому рекомендуется задавать имя скрипта обновления в виде <filename>{yymmdd}-{description}.sql</filename>, где <literal>yy</literal> - год, <literal>mm</literal> - месяц, <literal>dd</literal> - день, <literal>description</literal> - краткое описание скрипта. Например <filename>121003-addCodeToCategoryAttribute.sql</filename>.</para>
|
||||
<para>Скрипты обновления располагаются в каталоге <filename>/db/update</filename> модуля <structname>core</structname>. Для каждого типа СУБД, поддерживаемой приложением, создается свой набор скриптов и располагается в подкаталоге с именем, соответствующим значению перечисления <code>DbmsType</code>, например, <filename>/db/update/postgres</filename>. </para>
|
||||
<para>Скрипты обновления должны иметь имена, которые при сортировке в алфавитном порядке образуют правильную последовательность их выполнения (обычно это хронологическая последовательность их создания). Поэтому рекомендуется задавать имя скрипта обновления в виде <filename>{yymmdd}-{description}.sql</filename>, где <literal>yy</literal> - год, <literal>mm</literal> - месяц, <literal>dd</literal> - день, <literal>description</literal> - краткое описание скрипта. Например, <filename>121003-addCodeToCategoryAttribute.sql</filename>.</para>
|
||||
<para>Скрипты обновления можно группировать в подкаталоги, главное чтобы путь к скрипту с учетом подкаталога не нарушал хронологической последовательности. Например, можно создавать подкаталоги по номеру года или по году и месяцу.</para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
<para>В развернутом приложении скрипты создания и обновления БД располагаются в специальном <link linkend="db_dir">каталоге скриптов базы данных</link>, задаваемым свойством приложения <property>
|
||||
<link linkend="cuba.dbDir">cuba.dbDir</link>
|
||||
</property>.</para>
|
||||
<para>Скрипты представляют собой текстовые файлы с набором DDL и DML команд, разделенных символом "<literal>^</literal>". Символ "<literal>^</literal>" применяется для того, чтобы можно было применять разделитель "<literal>;</literal>" в составе сложных команд, например при создании функций или триггеров. Встроенный механизм исполнения скриптов разделяет входной файл на команды по разделителю "<literal>^</literal>" и выполняет каждую команду в отдельной транзакции. Это означает, что при необходимости можно сгруппировать несколько простых операторов (например <literal>insert</literal>), разделенных точкой с запятой, и обеспечить выполнение их в одной транзакции.</para>
|
||||
<para>Скрипты представляют собой текстовые файлы с набором DDL и DML команд, разделенных символом "<literal>^</literal>". Символ "<literal>^</literal>" применяется для того, чтобы можно было применять разделитель "<literal>;</literal>" в составе сложных команд, например, при создании функций или триггеров. Встроенный механизм исполнения скриптов разделяет входной файл на команды по разделителю "<literal>^</literal>" и выполняет каждую команду в отдельной транзакции. Это означает, что при необходимости можно сгруппировать несколько простых операторов (например, <literal>insert</literal>), разделенных точкой с запятой, и обеспечить выполнение их в одной транзакции.</para>
|
||||
<section>
|
||||
<title>Создание БД</title>
|
||||
<para>Базу данных можно создать двумя способами: с помощью скрипта сборки Gradle или на старте приложения путем запуска автоматического обновления.</para>
|
||||
@ -3672,7 +3672,7 @@ public void someServiceMethod() {
|
||||
<warning>
|
||||
<para>Если база данных по указанному в скрипте сборки URL существует, она полностью удаляется и создается заново.</para>
|
||||
</warning>
|
||||
<para>Чтобы инициализировать БД <link linkend="db_update">механизмом автоматического обновления</link> (например в развернутом приложении при отсутствии скрипта сборки), нужно выполнить следующее:<itemizedlist>
|
||||
<para>Чтобы инициализировать БД <link linkend="db_update">механизмом автоматического обновления</link> (например, в развернутом приложении при отсутствии скрипта сборки), нужно выполнить следующее:<itemizedlist>
|
||||
<listitem>
|
||||
<para>включить свойство приложения <property>
|
||||
<link linkend="cuba.automaticDatabaseUpdate">cuba.automaticDatabaseUpdate</link>
|
||||
@ -3881,7 +3881,7 @@ create index IDX_SALES_DOC_CARD on SALES_DOC (CARD_ID)^</programlisting></para>
|
||||
<section id="screens">
|
||||
<title>Экраны</title>
|
||||
<para>Экран универсального пользовательского интерфейса состоит из <link linkend="screen_xml">XML-дескриптора</link> и класса <link linkend="screen_controller">контроллера</link>. Дескриптор содержит ссылку на класс контроллера. </para>
|
||||
<para>Для того, чтобы экран можно было вызывать из главного меню или из Java кода (например из контроллера другого экрана), XML-дескриптор должен быть зарегистрирован в файле <link linkend="screens.xml">
|
||||
<para>Для того чтобы экран можно было вызывать из главного меню или из Java кода (например, из контроллера другого экрана), XML-дескриптор должен быть зарегистрирован в файле <link linkend="screens.xml">
|
||||
<filename>screens.xml</filename>
|
||||
</link> проекта.</para>
|
||||
<para>Главное меню приложения формируется отдельно для Web Client и Desktop Client на основе файлов <filename>
|
||||
@ -3935,7 +3935,7 @@ create index IDX_SALES_DOC_CARD on SALES_DOC (CARD_ID)^</programlisting></para>
|
||||
</code>), вызывают экраны выбора для поиска связанных сущностей. </para>
|
||||
<para>Для корректной работы <link linkend="standard_actions">стандартных действий</link> идентификатор экрана выбора в файле <link linkend="screens.xml">
|
||||
<filename>screens.xml</filename>
|
||||
</link> должен иметь вид <literal>{имя_сущности}.lookup</literal>, например <literal>sales$Customer.lookup</literal>.</para>
|
||||
</link> должен иметь вид <literal>{имя_сущности}.lookup</literal>, например, <literal>sales$Customer.lookup</literal>.</para>
|
||||
<para>Контроллер экрана выбора должен быть унаследован от класса <code>AbstractLookup</code>. В XML экрана в атрибуте <sgmltag>lookupComponent</sgmltag> должен быть указан компонент (например, <code>
|
||||
<link linkend="gui_Table">Table</link>
|
||||
</code>), из которого будет взят экземпляр сущности при выборе.</para>
|
||||
@ -3945,7 +3945,7 @@ create index IDX_SALES_DOC_CARD on SALES_DOC (CARD_ID)^</programlisting></para>
|
||||
<para>Экран редактирования предназначен для отображения и редактирования экземпляра сущности. Поддерживает функциональность установки редактируемого экземпляра и <link linkend="gui_Action">действия</link> по коммиту изменений в базу данных. Экран редактирования должен вызываться методом <code>openEditor()</code> с передачей экземпляра сущности.</para>
|
||||
<para>Для корректной работы <link linkend="standard_actions">стандартных действий</link> идентификатор экрана редактирования в файле <link linkend="screens.xml">
|
||||
<filename>screens.xml</filename>
|
||||
</link> должен иметь вид <literal>{имя_сущности}.edit</literal>, например <literal>sales$Customer.edit</literal>.</para>
|
||||
</link> должен иметь вид <literal>{имя_сущности}.edit</literal>, например, <literal>sales$Customer.edit</literal>.</para>
|
||||
<para>Контроллер экрана редактирования должен быть унаследован от класса <code>AbstractEditor</code>. В XML экрана в атрибуте <sgmltag>datasource</sgmltag> указывается источник данных, в который проставляется редактируемый экземпляр сущности. Для отображения действий, выполняющих коммит или отмену изменений, в XML можно использовать следующие стандартные фреймы с кнопками:<itemizedlist>
|
||||
<listitem>
|
||||
<para><literal>editWindowActions</literal> (файл <filename>com/haulmont/cuba/gui/edit-window.actions.xml</filename>) - содержит кнопки <guibutton>OK</guibutton> и <guibutton>Cancel</guibutton></para>
|
||||
@ -3966,7 +3966,7 @@ create index IDX_SALES_DOC_CARD on SALES_DOC (CARD_ID)^</programlisting></para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
<para>Таким образом, если в экран добавлен фрейм <literal>editWindowActions</literal>, то кнопка <guibutton>OK</guibutton> коммитит изменения и закрывает экран, а кнопка <guibutton>Cancel</guibutton> - закрывает без коммита. Если же добавлен фрейм <literal>extendedEditWindowActions</literal>, то кнопка <guibutton>OK</guibutton> только коммитит изменения, оставляя экран открытым, кнопка <guibutton>OK & Close</guibutton> коммитит и закрывает экран, кнопка <guibutton>Cancel</guibutton> - закрывает без коммита.</para>
|
||||
<para>Вместо стандартных фреймов для отображения действий можно использовать произвольные компоненты, например <code>
|
||||
<para>Вместо стандартных фреймов для отображения действий можно использовать произвольные компоненты, например, <code>
|
||||
<link linkend="gui_LinkButton">LinkButton</link>
|
||||
</code>.</para>
|
||||
</section>
|
||||
@ -4148,7 +4148,7 @@ public void init(Map<String, Object> params) {
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><code>getDialogParams()</code> - получить объект <code>DialogParams</code> для установки параметров отображения диалоговых окон (высота, ширина и пр.). Значения, установленные в этом объекте, влияют на следующий экран, открываемый в режиме модального диалога (<code>WindowManager.OpenType.DIALOG</code>). После отображения диалога они сбрасываются в значения по умолчанию.</para>
|
||||
<para>Таким образом, при устанавливать значения в <code>DialogParams</code> необходимо непосредственно перед вызовом другого экрана в режиме диалога методами <code>openWindow()</code>, <code>openLookup()</code>, <code>openEditor()</code>. Например:<programlisting>getDialogParams().setWidth(400);
|
||||
<para>Таким образом, устанавливать значения в <code>DialogParams</code> необходимо непосредственно перед вызовом другого экрана в режиме диалога методами <code>openWindow()</code>, <code>openLookup()</code>, <code>openEditor()</code>. Например:<programlisting>getDialogParams().setWidth(400);
|
||||
openEditor("sales$Customer.edit", customer, WindowManager.OpenType.DIALOG);</programlisting></para>
|
||||
<para>Если же сам текущий экран открывается в режиме модального диалога, то можно управлять параметрами его отображения, устанавливая параметры <code>DialogParams</code> в его методе <code>init()</code>. При этом установленные в <code>init()</code> параметры имеют приоритет над установленными в вызывающем коде.</para>
|
||||
</listitem>
|
||||
@ -4233,7 +4233,7 @@ protected void postValidate(ValidationErrors errors) {
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><code>close()</code> - закрыть данный экран. </para>
|
||||
<para>Метод принимает строковое значение, передаваемое далее в шаблонный метод <code>preClose()</code> и слушателям <code>CloseListener</code>. Таким образом заинтересованный код может получить информацию о причине закрытия экрана от кода, инициирующего закрытие. В частности, в экранах редактирования сущностей при закрытии экрана после коммита изменений рекомендуется использовать константу <code>Window.COMMIT_ACTION_ID</code>, без коммита изменений - константу <code>Window.CLOSE_ACTION_ID</code>.</para>
|
||||
<para>Метод принимает строковое значение, передаваемое далее в шаблонный метод <code>preClose()</code> и слушателям <code>CloseListener</code>. Таким образом, заинтересованный код может получить информацию о причине закрытия экрана от кода, инициирующего закрытие. В частности, в экранах редактирования сущностей при закрытии экрана после коммита изменений рекомендуется использовать константу <code>Window.COMMIT_ACTION_ID</code>, без коммита изменений - константу <code>Window.CLOSE_ACTION_ID</code>.</para>
|
||||
<para>Если какой-либо из источников данных содержит несохраненные изменения, перед закрытием экрана будет выдано диалоговое окно с соответствующим предупреждением. Тип предупреждения можно выбрать с помощью свойства приложения <property>
|
||||
<link linkend="cuba.gui.useSaveConfirmation">cuba.gui.useSaveConfirmation</link>
|
||||
</property>.</para>
|
||||
@ -4280,7 +4280,7 @@ protected void postValidate(ValidationErrors errors) {
|
||||
<para>Если редактируется не новый экземпляр, то в момент открытия экрана он перезагружается из базы данных с необходимым <link linkend="views">представлением</link>, указанным для главного источника данных. </para>
|
||||
<para>Изменения, вносимые в экземпляр, возвращаемый <code>getItem()</code>, отражаются на состоянии источника данных, и будут отправлены на Middleware при коммите экрана.</para>
|
||||
<warning>
|
||||
<para>Следует иметь в виду, что <code>getItem()</code> возвращает значение только после инициализации экрана методом <code>setItem()</code>. До этого момента, например в методах <code>init()</code> и <code>initItem()</code>, данный метод возвращает <code>null</code>.</para>
|
||||
<para>Следует иметь в виду, что <code>getItem()</code> возвращает значение только после инициализации экрана методом <code>setItem()</code>. До этого момента, например, в методах <code>init()</code> и <code>initItem()</code>, данный метод возвращает <code>null</code>.</para>
|
||||
<para>Однако в методе <code>init()</code> экземпляр сущности, переданный в <code>openEditor()</code>, можно получить из параметров следующим образом:<programlisting>@Override
|
||||
public void init(Map<String, Object> params) {
|
||||
Customer item = WindowParams.ITEM.getEntity(params);
|
||||
@ -4457,7 +4457,7 @@ protected boolean postCommit(boolean committed, boolean close) {
|
||||
<title>Реализация для разных типов клиентов</title>
|
||||
<para>Базовые классы контроллеров расположены в <link linkend="app_modules">модуле</link> <structname>gui</structname> <link linkend="base_projects">базового проекта</link> <structname>cuba</structname> и не содержат ссылок на классы реализации визуальных компонентов (<application>Swing</application> или <application>Vaadin</application>), что дает возможность использовать их в клиентах обоих типов. Вместо этого базовые классы контроллеров реализуют дополнительный интерфейс <code>Window.Wrapper</code> и делегируют выполнение "обернутому" окну. </para>
|
||||
<para>В то же время конкретные классы контроллеров могут быть расположены как в модуле <structname>gui</structname>, так и в <structname>web</structname> или <structname>desktop</structname>, в зависимости от применяемых в проекте клиентских <link linkend="app_tiers">блоков</link> и специфики экрана. Если контроллер является универсальным, но для разных типов клиента требуется дополнительная функциональность, ее можно определить в так называемых <firstterm>классах-компаньонах</firstterm>. </para>
|
||||
<para>Класс-компаньон располагается в модуле клиента соответствующего типа (<structname>web</structname> или <structname>desktop</structname>) и реализует интерфейс, задаваемый в использующем его контроллере. Класс компаньона задается в элементе <sgmltag>companions</sgmltag> XML-дескриптора экрана. Контроллер может получить ссылку на экземпляр компаньона с помощью инжекции или вызовом <code>getCompanion()</code>, и в нужный момент передать ему управление, например для дополнительной инициализации визуальных компонентов специфичным для данного типа клиента способом. </para>
|
||||
<para>Класс-компаньон располагается в модуле клиента соответствующего типа (<structname>web</structname> или <structname>desktop</structname>) и реализует интерфейс, задаваемый в использующем его контроллере. Класс компаньона задается в элементе <sgmltag>companions</sgmltag> XML-дескриптора экрана. Контроллер может получить ссылку на экземпляр компаньона с помощью инжекции или вызовом <code>getCompanion()</code>, и в нужный момент передать ему управление, например, для дополнительной инициализации визуальных компонентов специфичным для данного типа клиента способом. </para>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
@ -5567,7 +5567,7 @@ protected boolean postCommit(boolean committed, boolean close) {
|
||||
</figure>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para id="gui_attr_dateField_resolution">В большинстве бизнес-приложений нет необходимости отображать милисекунды или даже время. Точность представления даты или времени контролируется атрибутом <sgmltag>resolution</sgmltag>. Значение атрибута должно соответствовать перечислению <code>DateField.Resolution</code> − <literal>SEC</literal>, <literal>MIN</literal>, <literal>HOUR</literal>, <literal>DAY</literal>, <literal>MONTH</literal>, <literal>YEAR</literal>. По умолчанию точность определяется по аннотации <code>javax.persistence.Temporal</code> соответствующего атрибута <glossterm linkend="entity">сущности</glossterm>.</para>
|
||||
<para id="gui_attr_dateField_resolution">В большинстве бизнес-приложений нет необходимости отображать секунды или даже время. Точность представления даты или времени контролируется атрибутом <sgmltag>resolution</sgmltag>. Значение атрибута должно соответствовать перечислению <code>DateField.Resolution</code> − <literal>SEC</literal>, <literal>MIN</literal>, <literal>HOUR</literal>, <literal>DAY</literal>, <literal>MONTH</literal>, <literal>YEAR</literal>. По умолчанию точность определяется по аннотации <code>javax.persistence.Temporal</code> соответствующего атрибута <glossterm linkend="entity">сущности</glossterm>.</para>
|
||||
<para>Если <code>resolution="DAY"</code> и не указан атрибут <sgmltag>dateFormat</sgmltag>, то в качестве формата будет взят формат, указанный в <link linkend="main_message_pack">главном пакете сообщений</link> с ключом <sgmltag>dateFormat</sgmltag>.</para>
|
||||
<para>Если <code>resolution="MIN"</code> и не указан атрибут <sgmltag>dateFormat</sgmltag>, то в качестве формата будет взят формат, указанный в <link linkend="main_message_pack">главном пакете сообщений</link> с ключом <sgmltag>dateTimeFormat</sgmltag>.</para>
|
||||
<para>Ниже показано определения поля для ввода даты с точностью до месяца.</para>
|
||||
@ -5881,7 +5881,7 @@ protected boolean postCommit(boolean committed, boolean close) {
|
||||
<listitem>
|
||||
<para>Определить компонент можно также следующим образом:</para>
|
||||
<programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="source/section_gui/pickerField/pickerFieldProperty.txt" encoding="UTF-8" parse="text"/></programlisting>
|
||||
<para>Ппредварительно создается источник данных <literal>orderDs</literal> для некоторой сущности <code>Заказ (Order)</code>, имеющей ссылочный атрибут <code>customer</code>. В компоненте <sgmltag>pickerField</sgmltag> в атрибуте <link linkend="gui_attr_basic_datasource">datasource</link> указывается ссылка на созданный ранее источник данных, а в атрибуте <link linkend="gui_attr_basic_property">property</link> − название поля сущности, которое должно быть отображено в поле.</para>
|
||||
<para>Предварительно создается источник данных <literal>orderDs</literal> для некоторой сущности <code>Заказ (Order)</code>, имеющей ссылочный атрибут <code>customer</code>. В компоненте <sgmltag>pickerField</sgmltag> в атрибуте <link linkend="gui_attr_basic_datasource">datasource</link> указывается ссылка на созданный ранее источник данных, а в атрибуте <link linkend="gui_attr_basic_property">property</link> − название поля сущности, которое должно быть отображено в поле.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<warning>
|
||||
@ -6185,7 +6185,7 @@ protected boolean postCommit(boolean committed, boolean close) {
|
||||
<listitem>
|
||||
<para>Если в качестве значений списка используются экземпляры <glossterm linkend="entity">сущностей</glossterm>, нужно использовать атрибут <link linkend="gui_attr_basic_optionsDatasource">optionsDatasource</link> при описании компонента.</para>
|
||||
<programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="source/section_gui/lookupField/lookupFieldOptDs.txt" encoding="UTF-8" parse="text"/></programlisting>
|
||||
<para>Предварительно необходимо создать <link linkend="datasources">источник данных</link> <literal>orderDs</literal>, в который будет передан экземпляр редактируемой сущности из вызывающего экран кода, а также источник данных, содержащий коллецию сущностей для раскрывающегося списка (<literal>customersDs</literal>).</para>
|
||||
<para>Предварительно необходимо создать <link linkend="datasources">источник данных</link> <literal>orderDs</literal>, в который будет передан экземпляр редактируемой сущности из вызывающего экран кода, а также источник данных, содержащий коллекцию сущностей для раскрывающегося списка (<literal>customersDs</literal>).</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Ниже представлено описание раскрывающегося списка, значения которого заданы с помощью установки <link linkend="datasources">источника данных</link> и имени атрибута <glossterm linkend="entity">сущности</glossterm>. Атрибут сущности является перечислением (enum).</para>
|
||||
@ -7077,7 +7077,7 @@ protected boolean postCommit(boolean committed, boolean close) {
|
||||
</mediaobject>
|
||||
</figure>
|
||||
<para>Компонент реализован для блоков <structname>Web Client</structname> и <structname>Desktop Client</structname>. </para>
|
||||
<para>Для того чтобы создать иерархическую таблицу, необходимо в <glossterm linkend="screen_xml_glossentry">xml-дескрипторе</glossterm> задать иерархический <link linkend="datasources">источник данных</link>. Ниже представлено описание таблицы, отображающей иеархию продавцов.</para>
|
||||
<para>Для того чтобы создать иерархическую таблицу, необходимо в <glossterm linkend="screen_xml_glossentry">xml-дескрипторе</glossterm> задать иерархический <link linkend="datasources">источник данных</link>. Ниже представлено описание таблицы, отображающей иерархию продавцов.</para>
|
||||
<programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="source/section_gui/treeTable/treeTable.txt" encoding="UTF-8" parse="text"/></programlisting>
|
||||
<warning>
|
||||
<para>Обязательными для иерархической таблицы являются элементы <link linkend="gui_element_table_columns">columns</link> и <link linkend="gui_element_table_rows">rows</link>.</para>
|
||||
@ -7506,7 +7506,7 @@ protected boolean postCommit(boolean committed, boolean close) {
|
||||
<listitem>
|
||||
<para id="gui_attr_tokenList_simple">Установка атрибута <sgmltag>simple</sgmltag> в значение <literal>true</literal> позволяет сворачивать компонент, оставляя только кнопку добавления. При нажатии на кнопку добавления сразу показывается экран списка экземпляров <glossterm linkend="entity">сущности</glossterm>, для которой задан <link linkend="datasources">источник данных</link>.</para>
|
||||
<tip>
|
||||
<para>Уустановка атрибута <sgmltag>simple</sgmltag> в значение <literal>true</literal> имеет смысл только тогда, когда атрибут <link linkend="gui_attr_tokenList_lookup_lookup">lookup</link> установлен в значение <literal>true</literal>, а в атрибуте <link linkend="gui_attr_basic_lookupScreen">lookupScreen</link> задан идентификатор экрана для выбора значений.</para>
|
||||
<para>Установка атрибута <sgmltag>simple</sgmltag> в значение <literal>true</literal> имеет смысл только тогда, когда атрибут <link linkend="gui_attr_tokenList_lookup_lookup">lookup</link> установлен в значение <literal>true</literal>, а в атрибуте <link linkend="gui_attr_basic_lookupScreen">lookupScreen</link> задан идентификатор экрана для выбора значений.</para>
|
||||
</tip>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
@ -8679,7 +8679,7 @@ protected boolean postCommit(boolean committed, boolean close) {
|
||||
<para><emphasis role="bold">param</emphasis> − имя параметра экрана, в котором будет сохранен объект <code>AccessData</code></para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>В момент создания экрана загрузчик компонента <code>accessControl</code> проверяет наличие экземпляра <code>AccessData</code> в указанном параметре и если его там нет, создает новый экземпляр.</para>
|
||||
<para>В момент создания экрана загрузчик компонента <code>accessControl</code> проверяет наличие экземпляра <code>AccessData</code> в указанном параметре, и если его там нет, создает новый экземпляр.</para>
|
||||
<para>В дальнейшем в коде контроллера можно получить экземпляр <code>AccessData</code> из параметров экрана, например:</para>
|
||||
<programlisting>AbstractWfAccessData accessData = getContext().getParamValue("accessData");</programlisting>
|
||||
<para>При создании класса <code>AccessData</code> следует иметь в виду, что в параметры экрана-редактора всегда передается параметр <parameter>param$item</parameter>, содержащий текущий редактируемый экземпляр сущности. Однако этот экземпляр загружен по <link linkend="views">представлению</link> вызывающего экрана, а не по представлению редактора.</para>
|
||||
@ -8797,7 +8797,7 @@ protected boolean postCommit(boolean committed, boolean close) {
|
||||
<para>Быстрое переключение между представлениями</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Задание представления по умолчанию, которое будет применятся при открытии экрана с компонентом</para>
|
||||
<para>Задание представления по умолчанию, которое будет применяться при открытии экрана с компонентом</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Автосохранение настроек отображения в активном представлении</para>
|
||||
@ -8826,7 +8826,7 @@ protected boolean postCommit(boolean committed, boolean close) {
|
||||
<para><code>getCurrent()</code> − возвращает текущее активное представление или <code>null</code>, если представление не выбрано</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><code>setCurrent(Presentation p)</code> − уставнавливает активное представление</para>
|
||||
<para><code>setCurrent(Presentation p)</code> − устанавливает активное представление</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><code>getSettings(Presentation p)</code> − возвращает XML-элемент настроек отображения для указанного представления</para>
|
||||
@ -9305,14 +9305,14 @@ protected boolean postCommit(boolean committed, boolean close) {
|
||||
<section>
|
||||
<title>Тема в десктоп-приложениях</title>
|
||||
<para>В десктоп-приложениях базовой темой является тема <code>Nimbus</code>.</para>
|
||||
<para>Для внесения изменения в стандартную тему нужно создать пакет <code>rex.nimbus</code> в пакете <code>com.haulmont.ext.desktop</code> модуля <structname>desktop</structname>. В пакете <code>rex.nimbus</code> будут храниться файлы темы.</para>
|
||||
<para>Для внесения изменения в стандартную тему нужно создать пакет <code>res.nimbus</code> в пакете <code>com.haulmont.ext.desktop</code> модуля <structname>desktop</structname>. В пакете <code>res.nimbus</code> будут храниться файлы темы.</para>
|
||||
<para>В <link linkend="app_properties">файле свойств</link> для десктоп-приложения нужно установить свойство </para>
|
||||
<programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="source/section_gui/themes/desktop/example.txt" encoding="UTF-8" parse="text"/></programlisting>
|
||||
<para><emphasis role="bold">Примеры</emphasis></para>
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>Изменение пиктограммы для кнопки</para>
|
||||
<para>Если стоит задача заменить в десктоп-приложении какую-либо пиктограмму, нужно создать пакет <code>rex.nimbus.icons</code> в пакете <code>com.haulmont.ext.desktop</code> модуля <structname>desktop</structname> и поместить в него требуемое изображение.</para>
|
||||
<para>Если стоит задача заменить в десктоп-приложении какую-либо пиктограмму, нужно создать пакет <code>res.nimbus.icons</code> в пакете <code>com.haulmont.ext.desktop</code> модуля <structname>desktop</structname> и поместить в него требуемое изображение.</para>
|
||||
<para>Ниже представлена кнопка с переопределенной пиктограммой <filename>save.png</filename></para>
|
||||
<figure>
|
||||
<title/>
|
||||
@ -9324,7 +9324,7 @@ protected boolean postCommit(boolean committed, boolean close) {
|
||||
</figure>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Изменение цвета фона тесктовых полей, обязательных для ввода</para>
|
||||
<para>Изменение цвета фона текстовых полей, обязательных для ввода</para>
|
||||
<para>В пакете <code>res.nimbus</code> нужно создать файл <filename>nimbus.xml</filename> следующего содержания:</para>
|
||||
<programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="source/section_gui/themes/desktop/exapmle1_1.txt" encoding="UTF-8" parse="text"/></programlisting>
|
||||
<para>Элемент <sgmltag>ui-defaults</sgmltag> служит для переопределения значений свойств темы платформы, установленных по умолчанию.</para>
|
||||
@ -9366,7 +9366,7 @@ protected boolean postCommit(boolean committed, boolean close) {
|
||||
<para>Стандартной реализацией такого источника является класс <code>DatasourceImpl</code>, который используется, например, как главный источник данных в <link linkend="screen_edit">экранах редактирования</link> сущностей.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><code>CollectionDatasource</code> − источник данных, предназначенный для работы с коллекцией экземпляров сущности. Коллекция загружается при вызове метода <code>refresh()</code>, ключи экземпляров доступны через метод <code>getItemIds()</code>. Метод <code>setItem()</code> устанавливает, а <code>getItem()</code> возвращает "текущий" экземпляр коллекции, т.е. например соответствующий выбранной в данный момент строке таблицы.</para>
|
||||
<para><code>CollectionDatasource</code> − источник данных, предназначенный для работы с коллекцией экземпляров сущности. Коллекция загружается при вызове метода <code>refresh()</code>, ключи экземпляров доступны через метод <code>getItemIds()</code>. Метод <code>setItem()</code> устанавливает, а <code>getItem()</code> возвращает "текущий" экземпляр коллекции, т.е., например, соответствующий выбранной в данный момент строке таблицы.</para>
|
||||
<para>Способ загрузки коллекции сущностей определяется реализацией. Наиболее типичный - загрузка с Middleware через <code>
|
||||
<link linkend="dataService">DataService</link>
|
||||
</code>, при этом для формирования JPQL запроса используются методы <code>setQuery()</code>, <code>setQueryFilter()</code>.</para>
|
||||
@ -9394,7 +9394,7 @@ protected boolean postCommit(boolean committed, boolean close) {
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><code>PropertyDatasource</code> - подвид <code>NestedDatasource</code>, предназначенный для работы с одним экземпляром или коллекцией связанных сущностей, не являющихся встроенными (embedded).</para>
|
||||
<para>Стандартные реализации: для работы с одним экземпляром - <code>PropertyDatasourceImpl</code>, для работы с коллекцией - <code>CollectionPropertyDatasourceImpl</code>, <code>GroupPropertyDatasourceImpl</code>, <code>HierarchicalPropertyDatasourceImpl</code>. Последние реализуют также интерфейс <code>CollectionDatasource</code>, однако некоторые его нерелевантные методы, связанные с загрузкой, например <code>setQuery()</code>, выбрасывают <code>UnsupportedOperationException</code>.</para>
|
||||
<para>Стандартные реализации: для работы с одним экземпляром - <code>PropertyDatasourceImpl</code>, для работы с коллекцией - <code>CollectionPropertyDatasourceImpl</code>, <code>GroupPropertyDatasourceImpl</code>, <code>HierarchicalPropertyDatasourceImpl</code>. Последние реализуют также интерфейс <code>CollectionDatasource</code>, однако некоторые его нерелевантные методы, связанные с загрузкой, например, <code>setQuery()</code>, выбрасывают <code>UnsupportedOperationException</code>.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><code>EmbeddedDatasource</code> - подвид <code>NestedDatasource</code>, содержащий экземпляр встроенной сущности.</para>
|
||||
@ -9412,7 +9412,7 @@ protected boolean postCommit(boolean committed, boolean close) {
|
||||
<title>Создание источников данных</title>
|
||||
<section>
|
||||
<title>Декларативное создание</title>
|
||||
<para>Как правило источники данных объявляются декларативно в элементе <sgmltag>dsContext</sgmltag> дескриптора экрана. В зависимости от взаимного расположения элементов объявлений создаются источники двух разновидностей:<itemizedlist>
|
||||
<para>Как правило, источники данных объявляются декларативно в элементе <sgmltag>dsContext</sgmltag> дескриптора экрана. В зависимости от взаимного расположения элементов объявлений создаются источники двух разновидностей:<itemizedlist>
|
||||
<listitem>
|
||||
<para>если элемент расположен непосредственно в <sgmltag>dsContext</sgmltag>, создается обычный <code>Datasource</code> или <code>CollectionDatasource</code>, который содержит независимо загруженную сущность или коллекцию;</para>
|
||||
</listitem>
|
||||
@ -9427,7 +9427,7 @@ protected boolean postCommit(boolean committed, boolean close) {
|
||||
<para><sgmltag>datasource</sgmltag> - определяет источник данных, содержащий единственный экземпляр сущности. </para>
|
||||
<para>Атрибуты:<itemizedlist>
|
||||
<listitem>
|
||||
<para><sgmltag>id</sgmltag> - идентификатор источника, должен быть уникальным в для данного <code>DsContext</code>.</para>
|
||||
<para><sgmltag>id</sgmltag> - идентификатор источника, должен быть уникальным для данного <code>DsContext</code>.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><sgmltag>class</sgmltag> - Java класс сущности, которая будет содержаться в данном источнике</para>
|
||||
@ -9491,7 +9491,7 @@ public void init(Map<String, Object> params) {
|
||||
<para>Класс реализации источника выбирается неявно на основе имени элемента XML и, как было сказано выше, взаимного расположения элементов. Однако если необходимо применить нестандартный источник данных, его класс может быть явно указан в атрибуте <code>datasourceClass</code>. </para>
|
||||
</section>
|
||||
<section>
|
||||
<title>Прораммное создание</title>
|
||||
<title>Программное создание</title>
|
||||
<para>При необходимости создать источник данных в Java коде рекомендуется воспользоваться специальным классом <code>DsBuilder</code>. </para>
|
||||
<para>Экземпляр <code>DsBuilder</code> параметризуется цепочкой вызовов его методов в стиле текучего (fluent) интерфейса. Если установлены параметры <code>master</code> и <code>property</code>, то в результате будет создан <code>NestedDatasource</code>, в противном случае - <code>Datasource</code> или <code>CollectionDatasource</code>.</para>
|
||||
<para>Пример:<programlisting>CollectionDatasource ds = new DsBuilder(getDsContext())
|
||||
@ -9520,15 +9520,15 @@ public void init(Map<String, Object> params) {
|
||||
}
|
||||
}</programlisting></para>
|
||||
<para>Здесь <code>data</code> - поле базового класса, хранящее коллекцию загруженных экземпляров. Методы базового класса <code>detachListener()</code> и <code>attachListener()</code> управляют назначением на загруженные сущности слушателя, который оповещает источник данных об изменениях в полях экземпляров.</para>
|
||||
<para>Для создания нестандартного источника данных декларативным способом необходимо указать класс в атрибуте <sgmltag>datasourceClass</sgmltag> элемента XML. При программном содании через <code>DsBuilder</code> класс источника указывается вызовом <code>setDsClass()</code>.</para>
|
||||
<para>Для создания нестандартного источника данных декларативным способом необходимо указать класс в атрибуте <sgmltag>datasourceClass</sgmltag> элемента XML. При программном создании через <code>DsBuilder</code> класс источника указывается вызовом <code>setDsClass()</code>.</para>
|
||||
</section>
|
||||
<section>
|
||||
<title>Запросы в CollectionDatasourceImpl</title>
|
||||
<para>Класс <code> CollectionDatasourceImpl</code> и его наследники <code>GroupDatasourceImpl</code>, <code>HierarchicalDatasourceImpl</code> являются стандартной реализацией источников данных, работающих с коллекциями независимых экземпляров сущностей. Эти источники загружают данные через <code>DataService</code>, отправляя на Middleware запрос на языке JPQL. Далее рассмтриваются особенности формирования таких запросов.</para>
|
||||
<para>Класс <code> CollectionDatasourceImpl</code> и его наследники <code>GroupDatasourceImpl</code>, <code>HierarchicalDatasourceImpl</code> являются стандартной реализацией источников данных, работающих с коллекциями независимых экземпляров сущностей. Эти источники загружают данные через <code>DataService</code>, отправляя на Middleware запрос на языке JPQL. Далее рассматриваются особенности формирования таких запросов.</para>
|
||||
<section>
|
||||
<title>Возвращаемые значения</title>
|
||||
<para>Запрос должен возвращать сущности того типа, который указан при создании источника данных. Тип сущности при декларативном создании указывается в атрибуте <sgmltag>class</sgmltag> элемента XML, при создании через <code>DsBuilder</code> - в методе <code>setJavaClass()</code> или <code>setMetaClass()</code>.</para>
|
||||
<para>Кроме того, тип объекта в предложении <code>from</code> запроса должен соответствовать типу источника. Это необходимо для проведения автоматических транформаций запроса при наложении ограничений безопасности и др.</para>
|
||||
<para>Кроме того, тип объекта в предложении <code>from</code> запроса должен соответствовать типу источника. Это необходимо для проведения автоматических трансформаций запроса при наложении ограничений безопасности и др.</para>
|
||||
<para>Например, запрос источника данных типа <code>Customer</code> может выглядеть следующим образом:<programlisting>select c from sales$Customer c</programlisting></para>
|
||||
<para>Примеры недопустимых для источника типа <code>Customer</code> запросов:<programlisting>select c.id, c.name from sales$Customer c /* неверно - возвращает отдельные поля, а не весь объект Customer */
|
||||
|
||||
@ -9826,13 +9826,13 @@ taskHandler.execute();</programlisting><para>Подробная информац
|
||||
<title>Компоненты портала</title>
|
||||
<para>В данном руководстве <firstterm>порталом</firstterm> называется клиентский <link linkend="app_tiers">блок</link>, способный решать следующие задачи:<itemizedlist>
|
||||
<listitem>
|
||||
<para>предоставлять альтернативный веб-интерфейс, как правило предназначенный для пользователей за пределами организации;</para>
|
||||
<para>предоставлять альтернативный веб-интерфейс, как правило, предназначенный для пользователей за пределами организации;</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>предоставлять интерфейс для интеграции с мобильными приложениями и со сторонними системами.</para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
<para>Конкретное приложение может содержать несколько портальных модулей, предназначенных для различных целей, например в случае приложения, автоматизирующего бизнес такси это может быть публичный веб-сайт для клиентов, интеграционный модуль мобильного приложения заказа такси, интеграционный модуль мобильного приложения водителей, и т.д. </para>
|
||||
<para>Конкретное приложение может содержать несколько портальных модулей, предназначенных для различных целей, например, в случае приложения, автоматизирующего бизнес такси, это может быть публичный веб-сайт для клиентов, интеграционный модуль мобильного приложения заказа такси, интеграционный модуль мобильного приложения водителей, и т.д. </para>
|
||||
<para><link linkend="base_projects">Базовый проект</link> <structname>cuba</structname> платформы содержит в своем составе модуль <structname>portal</structname>, который является заготовкой для создания порталов в проектах. Он, во-первых, предоставляет базовую функциональность клиентского блока для работы с Middleware, а во-вторых, включает в себя универсальный <link linkend="rest_api">REST API</link> для работы с сущностями.</para>
|
||||
<section>
|
||||
<title>Базовая функциональность</title>
|
||||
@ -9857,7 +9857,7 @@ taskHandler.execute();</programlisting><para>Подробная информац
|
||||
<para><code>PortalSession</code> - специфичесий для портала объект <link linkend="userSession">пользовательской сессии</link>. Возвращается интерфейсом инфраструктуры <code>
|
||||
<link linkend="userSessionSource">UserSessionSource</link>
|
||||
</code>, а также статическим методом <code>PortalSessionProvider.getUserSession()</code>.</para>
|
||||
<para>Имеет дополнительный метод <code>isAuthenticated()</code>, возвращающий <code>true</code>, если данная сессия принадлежит не-анонимному, т.е. явно зарегистрировавшемуся с логином и паролем, пользователю.</para>
|
||||
<para>Имеет дополнительный метод <code>isAuthenticated()</code>, возвращающий <code>true</code>, если данная сессия принадлежит неанонимному, т.е. явно зарегистрировавшемуся с логином и паролем, пользователю.</para>
|
||||
<para>При первом обращении некоторого пользователя к порталу <code>SecurityContextHandlerInterceptor</code> создает для него (или привязывает уже имеющуюся) анонимную сессию, регистрируясь на Middleware с именем пользователя, указанным в свойстве приложения <property>
|
||||
<link linkend="cuba.portal.anonymousUserLogin">cuba.portal.anonymousUserLogin</link>
|
||||
</property>. Регистрация производится методом <code>
|
||||
@ -9960,7 +9960,7 @@ taskHandler.execute();</programlisting><para>Подробная информац
|
||||
<title>Назначенные задания CUBA</title>
|
||||
<para>Механизм назначенных заданий <application>CUBA</application> предназначен для запуска по расписанию методов произвольных бинов Spring в блоке Middleware. Целью данного механизма и отличием его от вышеупомянутого стандартного механизма <application> Spring Framework</application> являются: <itemizedlist>
|
||||
<listitem>
|
||||
<para>возможость конфигурирования заданий во время работы приложения без остановки сервера</para>
|
||||
<para>возможность конфигурирования заданий во время работы приложения без остановки сервера</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>координация выполнения синглтон-заданий в кластере Middleware, в том числе: <itemizedlist>
|
||||
@ -10129,7 +10129,7 @@ taskHandler.execute();</programlisting><para>Подробная информац
|
||||
<title>Вложения</title>
|
||||
<para>Объект <code>EmailAttachment</code> - обёртка, хранящая вложение в виде массива байт (поле <code>data</code>), имя файла (поле <code>name</code>), и при необходимости, уникальный для данного сообщения идентификатор вложения (необязательное, но полезное поле <code>contentId</code>). </para>
|
||||
<para>Идентификатор вложения может быть использован для вставки в сообщение изображений следующим образом:
|
||||
при создании <code>EmailAttachment</code> задаётся уникальный <code>contentId</code>, например <code>myPic</code>. В теле письма для вставки вложения необходимо в качестве пути использовать запись вида: <code>cid:myPic</code>. Т.е. для вставки изображения нужно указать следующий элемент HTML:<programlisting><img src="cid:myPic"/></programlisting></para>
|
||||
при создании <code>EmailAttachment</code> задаётся уникальный <code>contentId</code>, например, <code>myPic</code>. В теле письма для вставки вложения необходимо в качестве пути использовать запись вида: <code>cid:myPic</code>. Т.е. для вставки изображения нужно указать следующий элемент HTML:<programlisting><img src="cid:myPic"/></programlisting></para>
|
||||
</section>
|
||||
<section id="email_sending_properties">
|
||||
<title>Настройка параметров отправки</title>
|
||||
@ -10225,7 +10225,7 @@ taskHandler.execute();</programlisting><para>Подробная информац
|
||||
</section>
|
||||
<section>
|
||||
<title>Применение</title>
|
||||
<para>Для того, чтобы некоторая сущность могла иметь динамические атрибуты, ее класс необходимо унаследовать от <code>CategorizedEntity</code>, и, соответственно, обеспечить в таблице наличие поля <database>CATEGORY_ID</database> типа <code>UUID</code>.</para>
|
||||
<para>Для того чтобы некоторая сущность могла иметь динамические атрибуты, ее класс необходимо унаследовать от <code>CategorizedEntity</code>, и, соответственно, обеспечить в таблице наличие поля <database>CATEGORY_ID</database> типа <code>UUID</code>.</para>
|
||||
<para>Для включения динамических атрибутов в экран редактирования сущности необходимо выполнить следующее:<itemizedlist>
|
||||
<listitem>
|
||||
<para>В секции <sgmltag>dsContext</sgmltag> необходимо объявить два источника данных:<itemizedlist>
|
||||
@ -10304,10 +10304,10 @@ taskHandler.execute();</programlisting><para>Подробная информац
|
||||
<para>Статистика хранится в таблице <database>SYS_ENTITY_STATISTICS</database>, соответствующей сущности <code>EntityStatistics</code>. Заполнить статистику можно как вручную, внося соответствующие записи в таблицу, так и автоматически с помощью метода <code>refreshStatistics()</code> JMX-бина <code>
|
||||
<link linkend="persistenceManagerMBean">PersistenceManagerMBean</link>
|
||||
</code>. При указании в качестве параметра имени сущности статистика будет собрана только для данной сущности, в противном случае - для всех. Сбор статистики может занять значительное время и вызвать нежелательную нагрузку на БД, поэтому выполнять его нужно либо вручную, либо <link linkend="scheduled_tasks_cuba">назначенным заданием</link> в подходящее время.</para>
|
||||
<para>Программный доступ к статистике осуществляется с помощью интерфейса <code>PersistenceManagerAPI</code> на Middleware и <code>PersistenceManagerService</code> на клиентском уровне. Статистика кэшируется в памяти, поэтому если изменения статистики вносятся напрямую в базу данных, для всупления их в силу необходимо перезапустить сервер или вызвать метод <code>PersistenceManagerMBean.flushStatisticsCache()</code>.</para>
|
||||
<para>Программный доступ к статистике осуществляется с помощью интерфейса <code>PersistenceManagerAPI</code> на Middleware и <code>PersistenceManagerService</code> на клиентском уровне. Статистика кэшируется в памяти, поэтому если изменения статистики вносятся напрямую в базу данных, для вступления их в силу необходимо перезапустить сервер или вызвать метод <code>PersistenceManagerMBean.flushStatisticsCache()</code>.</para>
|
||||
<para>Рассмотрим атрибуты <code>EntityStatistics</code> и их влияние на поведение системы.<itemizedlist>
|
||||
<listitem>
|
||||
<para><code>name</code> (колонка <database>NAME</database>) - тип сущности в виде имени <link linkend="metaClass">мета-класса</link>, например <code>sales$Customer</code>.</para>
|
||||
<para><code>name</code> (колонка <database>NAME</database>) - тип сущности в виде имени <link linkend="metaClass">мета-класса</link>, например, <code>sales$Customer</code>.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><code>instanceCount</code> (колонка <database>INSTANCE_COUNT</database>) - примерное текущее количество экземпляров сущности. </para>
|
||||
@ -10357,7 +10357,7 @@ taskHandler.execute();</programlisting><para>Подробная информац
|
||||
<para><code>LoggedEntity</code> описывает тип сущности, изменения которой необходимо журналировать. Атрибуты <code>LoggedEntity</code>:</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><code>name</code> (колонка <database>NAME</database>) - тип сущности в виде имени <link linkend="metaClass">мета-класса</link>, например <code>sales$Customer</code>.</para>
|
||||
<para><code>name</code> (колонка <database>NAME</database>) - тип сущности в виде имени <link linkend="metaClass">мета-класса</link>, например, <code>sales$Customer</code>.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><code>auto</code> (колонка <database>AUTO</database>) - нужно ли журналировать изменения при вызове <code>EntityLogAPI</code> с параметром <code>auto = true</code> (т.е. из <link linkend="entity_listeners">Entity Listeners</link>).</para>
|
||||
@ -10641,7 +10641,7 @@ try {
|
||||
<constructor-arg index="0" ref="sqlSessionFactory" />
|
||||
</bean></programlisting></para>
|
||||
<para>В параметре <code>mapperLocations</code> задается путь (по правилам интерфейса <code>ResourceLoader</code> <application>Spring</application>) к файлам отображений <application>MyBatis</application>. </para>
|
||||
<para>Пример файла отбражения для загрузки экземпляра сущности <code>Заказ</code> вместе со связанным <code>Покупателем</code> и коллекцией <code>Пунктов заказа</code>:<programlisting><?xml version="1.0" encoding="UTF-8" ?>
|
||||
<para>Пример файла отображения для загрузки экземпляра сущности <code>Заказ</code> вместе со связанным <code>Покупателем</code> и коллекцией <code>Пунктов заказа</code>:<programlisting><?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
@ -10987,7 +10987,7 @@ public class ExtUser extends User {
|
||||
}</programlisting></para>
|
||||
<para>В аннотации <code>
|
||||
<link linkend="entity_annotation">@Entity</link>
|
||||
</code> должно быть указано новое имя сущности. Так как базовая сущность не объявляет <link linkend="inheritance_annotation">стратегию наследования</link>, то по умолчанию это <code>SINGLE_TABLE</code>. Это означает, что унаследованная сущность будет хранится в той же таблице, что и базовая, и аннотация <code>
|
||||
</code> должно быть указано новое имя сущности. Так как базовая сущность не объявляет <link linkend="inheritance_annotation">стратегию наследования</link>, то по умолчанию это <code>SINGLE_TABLE</code>. Это означает, что унаследованная сущность будет храниться в той же таблице, что и базовая, и аннотация <code>
|
||||
<link linkend="table_annotation">@Table</link>
|
||||
</code> не требуется. Другие аннотации базовой сущности - <code>
|
||||
<link linkend="namePattern">@NamePattern</link>
|
||||
@ -11025,10 +11025,10 @@ public class ExtUser extends User {
|
||||
<para role="bold">Если поиск дал результат, то найденный элемент <emphasis role="bold">переопределяется</emphasis>.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Если поиск не дал результата, то определяется сколько в базовом дескрипторе элементов по данному пути и с данным именем. Если ровно один - он <emphasis role="bold">переопределяется</emphasis>.</para>
|
||||
<para>Если поиск не дал результата, то определяется, сколько в базовом дескрипторе элементов по данному пути и с данным именем. Если ровно один - он <emphasis role="bold">переопределяется</emphasis>.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Если поиск не дал результата, и в базовом дескрипторе по данному пути с данным именем нет элементов либо их больше одного, <emphasis role="bold">добавляется</emphasis> новый элемент.</para>
|
||||
<para>Если поиск не дал результата, и в базовом дескрипторе по данному пути с данным именем нет элементов, либо их больше одного, <emphasis role="bold">добавляется</emphasis> новый элемент.</para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
</listitem>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -103,7 +103,7 @@
|
||||
<para>Скачайте последнюю версию <application>JDK 7</application>, например, <filename>jdk-7u5-windows-x64.exe.</filename></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Запустите файл <filename>jdk-7u5-windows-x64.exe</filename> и установите все компоненты следуя инструкциям программы-устновщика.</para>
|
||||
<para>Запустите файл <filename>jdk-7u5-windows-x64.exe</filename> и установите все компоненты следуя инструкциям программы-установщика.</para>
|
||||
</listitem>
|
||||
<listitem id="path_setting">
|
||||
<para>Создайте переменную среды <envar>JAVA_HOME</envar>. В качестве значения переменной окружения <envar>JAVA_HOME</envar> установите путь к каталогу установки <application>JDK</application>, например, <filename>C:\Program Files\Java\jdk1.7.0_05</filename>.</para>
|
||||
|
@ -1,414 +1,414 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!DOCTYPE glossary PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []>
|
||||
<!-- This document was created with Syntext Serna Free. --><glossary id="glossary">
|
||||
<title>Основные определения и понятия</title>
|
||||
<glossdiv>
|
||||
<title>А</title>
|
||||
<glossentry id="artifact">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Артефакт</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>В контексте данного руководства под артефактом понимается файл (обычно JAR или ZIP), содержащий исполняемый или другой код, получившийся в результате сборки проекта. Артефакт имеет соответствующее некоторым правилам имя и версию, и может хранится в <glossterm linkend="artifact_repository">репозитории</glossterm> артефактов.</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>Б</title>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">БД</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Реляционная база данных</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry id="browser_glossentry">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Браузер сущностей</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Экранная форма, на которой размещается таблица со списком <glossterm linkend="entity">сущностей</glossterm>, а также кнопки создания, редактирования, удаления сущности.</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>В</title>
|
||||
<glossentry id="dependency_injection">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Внедрение зависимости</emphasis>
|
||||
</glossterm>
|
||||
<acronym>Dependency Injection</acronym>
|
||||
<glossdef>
|
||||
<para>Известно также как принцип Inversion Of Control (IoC). Механизм для получения ссылок на используемые объекты, при котором объект только декларирует, от каких объектов он зависит, а <glossterm linkend="container">контейнер</glossterm> создает нужные объекты и инжектирует в зависимый объект. </para>
|
||||
<para>См. <ulink url="http://ru.wikipedia.org/wiki/%D0%92%D0%BD%D0%B5%D0%B4%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B7%D0%B0%D0%B2%D0%B8%D1%81%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B8">http://ru.wikipedia.org/wiki/Внедрение_зависимости</ulink></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>Г</title>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">Главный пакет сообщений</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>См. <xref linkend="main_message_pack"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>З</title>
|
||||
<glossentry id="lazy_loading_glossterm">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Загрузка по требованию</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>См. <xref linkend="lazy_loading"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>И</title>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">Источник данных</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>См. <xref linkend="datasources"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>К</title>
|
||||
<glossentry id="container">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Контейнер</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Контейнер управляет жизненным циклом и конфигурацией программных объектов. Является базовым компонентом технологии Dependency Injection (или Inversion of Control).</para>
|
||||
<para>В платформе <productname>CUBA</productname> используется контейнер <application>Spring Framework</application>. Для получения более подробной информации см. <xref linkend="additional_info"/> </para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry id="screen_controller_glossentry">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Контроллер экрана</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para><code>Java</code> класс, содержащий логику инициализации и обработки событий экрана. Связан с <glossterm linkend="screen_xml_glossentry">XML-дескриптором</glossterm> экрана.</para>
|
||||
<para>См. <xref linkend="screen_controller"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>Л</title>
|
||||
<glossentry id="local_attribute">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Локальный атрибут</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Атрибут сущности, не являющийся ссылкой или коллекцией ссылок на другую сущность. Значения всех локальных атрибутов сущности как правило хранятся в одной таблице (исключение составляют некоторые стратегии наследования сущностей). </para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>П</title>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">Пакет локализованных сообщений</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>См. <xref linkend="message_packs"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry id="persistence_context">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Персистентный контекст</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Набор экземпляров сущностей, загруженных из базы данных или только что созданных. Персистентный контекст является кэшем данных в рамках текущей транзакции. При коммите транзакции все изменения сущностей в персистентном контексте сохраняются в БД. </para>
|
||||
<para>См. <xref linkend="entityManager"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">Представление</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>См. <xref linkend="views"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>Р</title>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">Рабочий каталог</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Локальный каталог файловой системы, в котором содержится проект приложения. Содержит скрипты сборки <filename>build.gradle</filename>, <filename>settings.gradle</filename> и проектные файлы <application>IDE</application>.</para>
|
||||
<para>См. <xref linkend="chapter_development"/> </para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry id="artifact_repository">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Репозиторий артефактов</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Сервер, осуществляющий хранение <glossterm linkend="artifact">артефактов</glossterm> в определенной структуре. В процессе сборки некоторого проекта из репозитория загружаются артефакты, от которых зависит данный проект.</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>С</title>
|
||||
<glossentry id="entity">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Сущность</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Основной элемент модели данных, см. <xref linkend="data_model"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>Э</title>
|
||||
<glossentry id="eager_fetching">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Энергичная загрузка</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Загрузка данных подклассов и связанных объектов одновременно с основной запрашиваемой сущностью.</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>A</title>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">Application Tiers</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>См. <xref linkend="app_tiers"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry id="app_properties_glossentry">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Application Properties</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Свойства приложения − именованные данные различных типов, определяющие всевозможные аспекты конфигурации и функционирования приложения.</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">Application Units</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>См. <xref linkend="app_tiers"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv lang="ru">
|
||||
<title>D</title>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">Datasource</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>См. <xref linkend="datasources"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>E</title>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">Eager Fetching</emphasis>
|
||||
</glossterm>
|
||||
<glosssee otherterm="eager_fetching"/>
|
||||
</glossentry>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">EntityManager</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Программный компонент среднего слоя, служащий для работы с персистентными <link linkend="data_model">сущностями</link>.</para>
|
||||
<para>См. <xref linkend="entityManager"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>I</title>
|
||||
<glossentry id="interceptor">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Interceptor</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Элемент AOP (Aspect Oriented Programming), позволяющий изменить или расширить обычный вызов метода объекта.</para>
|
||||
<para>См. <ulink url="http://en.wikipedia.org/wiki/Interceptor_pattern">http://en.wikipedia.org/wiki/Interceptor_pattern</ulink></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>J</title>
|
||||
<glossentry id="javaee_web_profile">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Java EE Web Profile</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Упрощенный профиль Java Enterprise Edition, разработанный для веб-приложений, для которых не требуются такие технологии как EJB, JTA и т.д.</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry id="jmx">
|
||||
<glossterm>
|
||||
<emphasis role="bold">JMX</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Java Management Extensions − технология, которая предоставляет инструменты для управления приложениями, объектами системы, устройствами. Определяет стандарт для написания JMX-компонентов − <link linkend="jmx_beans">MBeans</link>. </para>
|
||||
<para>Более подробную информацию можно найти по адресу: <ulink url="http://www.oracle.com/technetwork/java/javase/tech/javamanagement-140525.html">http://www.oracle.com/technetwork/java/javase/tech/javamanagement-140525.html</ulink></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry id="jpa">
|
||||
<glossterm>
|
||||
<emphasis role="bold">JPA</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Java Persistence API - стандартная спецификация технологии объектно-реляционного отображения (<link linkend="orm">ORM</link>). В платформе <productname>CUBA</productname> используется фреймворк <application>Apache OpenJPA</application>, реализующий эту спецификацию.</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry id="jpql">
|
||||
<glossterm>
|
||||
<emphasis role="bold">JPQL</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Платформо-независимый объектно-ориентированный язык запросов, определенный как часть спецификации <glossterm linkend="jpa">JPA</glossterm>. </para>
|
||||
<para>Более подробную информацию можно найти по адресу: <ulink url="http://openjpa.apache.org/builds/2.2.0/apache-openjpa/docs/jpa_langref.html">http://openjpa.apache.org/builds/2.2.0/apache-openjpa/docs/jpa_langref.html</ulink></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>L</title>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">Lazy loading</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>См. <xref linkend="lazy_loading"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>M</title>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">Managed Beans</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Программные компоненты <glossterm linkend="middleware">Middleware</glossterm>, содержащие бизнес-логику приложения.</para>
|
||||
<para>См. <xref linkend="managed_beans"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">MBeans</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para><link linkend="managed_beans">Managed Beans</link>, имеющие <glossterm linkend="jmx">JMX</glossterm>-интерфейс. Как правило, имеют внутреннее состояние (например, кэш, конфигурационные данные или статистику), к которому нужно обеспечить доступ через JMX.
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry id="middleware_glossentry">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Middleware</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Средний слой − <link linkend="app_tiers">уровень</link> приложения, содержащий бизнес-логику, работающий с базой данных, и предоставляющий общий интерфейс для верхних (клиентских) уровней приложения.</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>O</title>
|
||||
<glossentry id="optimistic_locking">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Optimistic locking</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Оптимистичная блокировка - способ управления совместным доступом к данным различными пользователями, при котором предполагается, что возможность одновременного изменения ими одного и того же экземпляра сущности мала. В этом случае блокировка как таковая отсутствует, вместо нее в момент сохранения изменений производится проверка, нет ли в БД более новой версии данных, сохраненной другим пользователем. Если есть, выбрасывается исключение, и текущий пользователь должен снова загрузить данный экземпляр сущности.</para>
|
||||
<para>См. также <ulink url="http://en.wikipedia.org/wiki/Optimistic_concurrency_control">http://en.wikipedia.org/wiki/Optimistic_concurrency_control</ulink></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">ORM</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Object-Relational Mapping - объектно-реляционное отображение - технология связывания таблиц реляционной базы данных с объектами языка программирования. </para>
|
||||
<para>См. <xref linkend="orm"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv lang="ru">
|
||||
<title>P</title>
|
||||
<glossentry id="pojo">
|
||||
<glossterm>
|
||||
<emphasis role="bold">POJO</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Plain Old Java Object − «простой Java-объект в старом стиле» − Java-объект, не унаследованный ни от какого специфического класса и не реализующий никаких служебных интерфейсов сверх тех, которые нужны для описания бизнес-логики. </para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>S</title>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">Services</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Сервисы среднего слоя предоставляют интерфейс для вызова бизнес-логики клиентами и образуют границу <glossterm linkend="middleware_glossentry">Middleware</glossterm>. Сервисы могут содержать бизнес-логику внутри себя, либо делегировать выполнение <link linkend="managed_beans">Managed Beans</link>.</para>
|
||||
<para>См. <xref linkend="services"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">Soft deletion</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>TODO</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>U</title>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">UI</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>User Interface - пользовательский интерфейс</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv lang="ru">
|
||||
<title>V</title>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">View</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>См. <xref linkend="views"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv lang="ru">
|
||||
<title>X</title>
|
||||
<glossentry id="screen_xml_glossentry">
|
||||
<glossterm>
|
||||
<emphasis role="bold">XML-дескриптор</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Файл в формате XML, содержащий описание <link linkend="datasources">источников данных</link> и расположения визуальных компонентов экрана.</para>
|
||||
<para>См. <xref linkend="screen_xml"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
</glossary>
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!DOCTYPE glossary PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []>
|
||||
<!-- This document was created with Syntext Serna Free. --><glossary id="glossary">
|
||||
<title>Основные определения и понятия</title>
|
||||
<glossdiv>
|
||||
<title>А</title>
|
||||
<glossentry id="artifact">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Артефакт</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>В контексте данного руководства под артефактом понимается файл (обычно JAR или ZIP), содержащий исполняемый или другой код, получившийся в результате сборки проекта. Артефакт имеет соответствующее некоторым правилам имя и версию, и может хранится в <glossterm linkend="artifact_repository">репозитории</glossterm> артефактов.</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>Б</title>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">БД</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Реляционная база данных</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry id="browser_glossentry">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Браузер сущностей</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Экранная форма, на которой размещается таблица со списком <glossterm linkend="entity">сущностей</glossterm>, а также кнопки создания, редактирования, удаления сущности.</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>В</title>
|
||||
<glossentry id="dependency_injection">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Внедрение зависимости</emphasis>
|
||||
</glossterm>
|
||||
<acronym>Dependency Injection</acronym>
|
||||
<glossdef>
|
||||
<para>Известно также как принцип Inversion Of Control (IoC). Механизм для получения ссылок на используемые объекты, при котором объект только декларирует, от каких объектов он зависит, а <glossterm linkend="container">контейнер</glossterm> создает нужные объекты и инжектирует в зависимый объект. </para>
|
||||
<para>См. <ulink url="http://ru.wikipedia.org/wiki/%D0%92%D0%BD%D0%B5%D0%B4%D1%80%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B7%D0%B0%D0%B2%D0%B8%D1%81%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D0%B8">http://ru.wikipedia.org/wiki/Внедрение_зависимости</ulink></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>Г</title>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">Главный пакет сообщений</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>См. <xref linkend="main_message_pack"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>З</title>
|
||||
<glossentry id="lazy_loading_glossterm">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Загрузка по требованию</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>См. <xref linkend="lazy_loading"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>И</title>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">Источник данных</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>См. <xref linkend="datasources"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>К</title>
|
||||
<glossentry id="container">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Контейнер</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Контейнер управляет жизненным циклом и конфигурацией программных объектов. Является базовым компонентом технологии Dependency Injection (или Inversion of Control).</para>
|
||||
<para>В платформе <productname>CUBA</productname> используется контейнер <application>Spring Framework</application>. Для получения более подробной информации см. <xref linkend="additional_info"/> </para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry id="screen_controller_glossentry">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Контроллер экрана</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para><code>Java</code> класс, содержащий логику инициализации и обработки событий экрана. Связан с <glossterm linkend="screen_xml_glossentry">XML-дескриптором</glossterm> экрана.</para>
|
||||
<para>См. <xref linkend="screen_controller"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>Л</title>
|
||||
<glossentry id="local_attribute">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Локальный атрибут</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Атрибут сущности, не являющийся ссылкой или коллекцией ссылок на другую сущность. Значения всех локальных атрибутов сущности, как правило, хранятся в одной таблице (исключение составляют некоторые стратегии наследования сущностей). </para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>П</title>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">Пакет локализованных сообщений</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>См. <xref linkend="message_packs"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry id="persistence_context">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Персистентный контекст</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Набор экземпляров сущностей, загруженных из базы данных или только что созданных. Персистентный контекст является кэшем данных в рамках текущей транзакции. При коммите транзакции все изменения сущностей в персистентном контексте сохраняются в БД. </para>
|
||||
<para>См. <xref linkend="entityManager"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">Представление</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>См. <xref linkend="views"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>Р</title>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">Рабочий каталог</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Локальный каталог файловой системы, в котором содержится проект приложения. Содержит скрипты сборки <filename>build.gradle</filename>, <filename>settings.gradle</filename> и проектные файлы <application>IDE</application>.</para>
|
||||
<para>См. <xref linkend="chapter_development"/> </para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry id="artifact_repository">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Репозиторий артефактов</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Сервер, осуществляющий хранение <glossterm linkend="artifact">артефактов</glossterm> в определенной структуре. В процессе сборки некоторого проекта из репозитория загружаются артефакты, от которых зависит данный проект.</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>С</title>
|
||||
<glossentry id="entity">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Сущность</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Основной элемент модели данных, см. <xref linkend="data_model"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>Э</title>
|
||||
<glossentry id="eager_fetching">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Энергичная загрузка</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Загрузка данных подклассов и связанных объектов одновременно с основной запрашиваемой сущностью.</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>A</title>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">Application Tiers</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>См. <xref linkend="app_tiers"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry id="app_properties_glossentry">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Application Properties</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Свойства приложения − именованные данные различных типов, определяющие всевозможные аспекты конфигурации и функционирования приложения.</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">Application Units</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>См. <xref linkend="app_tiers"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv lang="ru">
|
||||
<title>D</title>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">Datasource</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>См. <xref linkend="datasources"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>E</title>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">Eager Fetching</emphasis>
|
||||
</glossterm>
|
||||
<glosssee otherterm="eager_fetching"/>
|
||||
</glossentry>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">EntityManager</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Программный компонент среднего слоя, служащий для работы с персистентными <link linkend="data_model">сущностями</link>.</para>
|
||||
<para>См. <xref linkend="entityManager"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>I</title>
|
||||
<glossentry id="interceptor">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Interceptor</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Элемент AOP (Aspect Oriented Programming), позволяющий изменить или расширить обычный вызов метода объекта.</para>
|
||||
<para>См. <ulink url="http://en.wikipedia.org/wiki/Interceptor_pattern">http://en.wikipedia.org/wiki/Interceptor_pattern</ulink></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>J</title>
|
||||
<glossentry id="javaee_web_profile">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Java EE Web Profile</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Упрощенный профиль Java Enterprise Edition, разработанный для веб-приложений, для которых не требуются такие технологии как EJB, JTA и т.д.</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry id="jmx">
|
||||
<glossterm>
|
||||
<emphasis role="bold">JMX</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Java Management Extensions − технология, которая предоставляет инструменты для управления приложениями, объектами системы, устройствами. Определяет стандарт для написания JMX-компонентов − <link linkend="jmx_beans">MBeans</link>. </para>
|
||||
<para>Более подробную информацию можно найти по адресу: <ulink url="http://www.oracle.com/technetwork/java/javase/tech/javamanagement-140525.html">http://www.oracle.com/technetwork/java/javase/tech/javamanagement-140525.html</ulink></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry id="jpa">
|
||||
<glossterm>
|
||||
<emphasis role="bold">JPA</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Java Persistence API - стандартная спецификация технологии объектно-реляционного отображения (<link linkend="orm">ORM</link>). В платформе <productname>CUBA</productname> используется фреймворк <application>Apache OpenJPA</application>, реализующий эту спецификацию.</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry id="jpql">
|
||||
<glossterm>
|
||||
<emphasis role="bold">JPQL</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Платформо-независимый объектно-ориентированный язык запросов, определенный как часть спецификации <glossterm linkend="jpa">JPA</glossterm>. </para>
|
||||
<para>Более подробную информацию можно найти по адресу: <ulink url="http://openjpa.apache.org/builds/2.2.0/apache-openjpa/docs/jpa_langref.html">http://openjpa.apache.org/builds/2.2.0/apache-openjpa/docs/jpa_langref.html</ulink></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>L</title>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">Lazy loading</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>См. <xref linkend="lazy_loading"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>M</title>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">Managed Beans</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Программные компоненты <glossterm linkend="middleware">Middleware</glossterm>, содержащие бизнес-логику приложения.</para>
|
||||
<para>См. <xref linkend="managed_beans"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">MBeans</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para><link linkend="managed_beans">Managed Beans</link>, имеющие <glossterm linkend="jmx">JMX</glossterm>-интерфейс. Как правило, имеют внутреннее состояние (например, кэш, конфигурационные данные или статистику), к которому нужно обеспечить доступ через JMX.
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry id="middleware_glossentry">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Middleware</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Средний слой − <link linkend="app_tiers">уровень</link> приложения, содержащий бизнес-логику, работающий с базой данных, и предоставляющий общий интерфейс для верхних (клиентских) уровней приложения.</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>O</title>
|
||||
<glossentry id="optimistic_locking">
|
||||
<glossterm>
|
||||
<emphasis role="bold">Optimistic locking</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Оптимистичная блокировка - способ управления совместным доступом к данным различными пользователями, при котором предполагается, что возможность одновременного изменения ими одного и того же экземпляра сущности мала. В этом случае блокировка как таковая отсутствует, вместо нее в момент сохранения изменений производится проверка, нет ли в БД более новой версии данных, сохраненной другим пользователем. Если есть, выбрасывается исключение, и текущий пользователь должен снова загрузить данный экземпляр сущности.</para>
|
||||
<para>См. также <ulink url="http://en.wikipedia.org/wiki/Optimistic_concurrency_control">http://en.wikipedia.org/wiki/Optimistic_concurrency_control</ulink></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">ORM</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Object-Relational Mapping - объектно-реляционное отображение - технология связывания таблиц реляционной базы данных с объектами языка программирования. </para>
|
||||
<para>См. <xref linkend="orm"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv lang="ru">
|
||||
<title>P</title>
|
||||
<glossentry id="pojo">
|
||||
<glossterm>
|
||||
<emphasis role="bold">POJO</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Plain Old Java Object − «простой Java-объект в старом стиле» − Java-объект, не унаследованный ни от какого специфического класса и не реализующий никаких служебных интерфейсов сверх тех, которые нужны для описания бизнес-логики. </para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>S</title>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">Services</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Сервисы среднего слоя предоставляют интерфейс для вызова бизнес-логики клиентами и образуют границу <glossterm linkend="middleware_glossentry">Middleware</glossterm>. Сервисы могут содержать бизнес-логику внутри себя, либо делегировать выполнение <link linkend="managed_beans">Managed Beans</link>.</para>
|
||||
<para>См. <xref linkend="services"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">Soft deletion</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>TODO</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv>
|
||||
<title>U</title>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">UI</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>User Interface - пользовательский интерфейс</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv lang="ru">
|
||||
<title>V</title>
|
||||
<glossentry>
|
||||
<glossterm>
|
||||
<emphasis role="bold">View</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>См. <xref linkend="views"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
<glossdiv lang="ru">
|
||||
<title>X</title>
|
||||
<glossentry id="screen_xml_glossentry">
|
||||
<glossterm>
|
||||
<emphasis role="bold">XML-дескриптор</emphasis>
|
||||
</glossterm>
|
||||
<glossdef>
|
||||
<para>Файл в формате XML, содержащий описание <link linkend="datasources">источников данных</link> и расположения визуальных компонентов экрана.</para>
|
||||
<para>См. <xref linkend="screen_xml"/></para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
</glossdiv>
|
||||
</glossary>
|
||||
|
@ -111,7 +111,7 @@
|
||||
<title>Конфигурационные файлы</title>
|
||||
<section id="context.xml">
|
||||
<title>context.xml</title>
|
||||
<para>Файл <filename>context.xml</filename> является дескриптором развертывания приложения на сервере <application>Apache Tomcat</application>. В развернутом приложении этот файл располагается в подкаталоге <filename>META-INF</filename> каталога веб-приложения или WAR-файла, например <filename>tomcat/webapps/app-core/META-INF/context.xml</filename>. В проекте файлы данного типа находятся в каталогах <filename>/web/META-INF</filename> модулей <structname>core</structname>, <structname>web</structname>, <structname>portal</structname>.</para>
|
||||
<para>Файл <filename>context.xml</filename> является дескриптором развертывания приложения на сервере <application>Apache Tomcat</application>. В развернутом приложении этот файл располагается в подкаталоге <filename>META-INF</filename> каталога веб-приложения или WAR-файла, например, <filename>tomcat/webapps/app-core/META-INF/context.xml</filename>. В проекте файлы данного типа находятся в каталогах <filename>/web/META-INF</filename> модулей <structname>core</structname>, <structname>web</structname>, <structname>portal</structname>.</para>
|
||||
<para>Основное предназначение файла для блока <structname>Middleware</structname> - определить источник данных и поместить его в JNDI под именем, заданным свойством приложения <property>
|
||||
<link linkend="cuba.dataSourceJndiName">cuba.dataSourceJndiName</link>
|
||||
</property>.</para>
|
||||
@ -229,7 +229,7 @@
|
||||
<para><sgmltag>id</sgmltag> - идентификатор элемента, использующийся для формирования локализованного названия (см. ниже)</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><sgmltag>insertBefore</sgmltag>, <sgmltag>insertAfter</sgmltag> - идентификатор элемента меню, перед/после которого нужно вставить данный элемент. Используется в прикладном проекте для вставки элемента в нужное место меню, определенного в аналогичных файлах базовых проектов. Разумеется использовать для данного элемента нужно какой-нибудь один из этих атрибутов.</para>
|
||||
<para><sgmltag>insertBefore</sgmltag>, <sgmltag>insertAfter</sgmltag> - идентификатор элемента меню, перед/после которого нужно вставить данный элемент. Используется в прикладном проекте для вставки элемента в нужное место меню, определенного в аналогичных файлах базовых проектов. Разумеется, использовать для данного элемента нужно какой-нибудь один из этих атрибутов.</para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
<para>Элементы menu:<itemizedlist>
|
||||
@ -442,7 +442,7 @@ menu-config.sales$Customer.lookup=Customers</programlisting></para>
|
||||
<para><sgmltag>screen</sgmltag> - описатель экрана</para>
|
||||
<para>Атрибуты <sgmltag>screen</sgmltag>:<itemizedlist>
|
||||
<listitem>
|
||||
<para><sgmltag>id</sgmltag> - идентификатор экрана, по которому он доступен в программном коде (например в методах <code>IFrame.openWindow()</code> и т.п.) и в <filename>
|
||||
<para><sgmltag>id</sgmltag> - идентификатор экрана, по которому он доступен в программном коде (например, в методах <code>IFrame.openWindow()</code> и т.п.) и в <filename>
|
||||
<link linkend="menu.xml">menu.xml</link>
|
||||
</filename>.</para>
|
||||
</listitem>
|
||||
@ -540,7 +540,7 @@ menu-config.sales$Customer.lookup=Customers</programlisting></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><sgmltag>lazy</sgmltag> - для ссылочных атрибутов признак того, что данный атрибут нужно не включать в Fetch Plan, а загружать отдельным SQL запросом, инициированным обращением к атрибуту. Необязательный атрибут, по умолчанию <literal>false</literal>.</para>
|
||||
<para>Рекомендуется использовать <sgmltag>lazy</sgmltag> для атрибутов-коллекций, если таких атрибутов больше одного для данного графа представлениий. Т.е. устанавливайте <literal>lazy = "true"</literal> для всех коллекций, кроме одной.</para>
|
||||
<para>Рекомендуется использовать <sgmltag>lazy</sgmltag> для атрибутов-коллекций, если таких атрибутов больше одного для данного графа представлений. Т.е. устанавливайте <literal>lazy = "true"</literal> для всех коллекций, кроме одной.</para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
<para>Элементы <sgmltag>property</sgmltag>:<itemizedlist>
|
||||
@ -636,7 +636,7 @@ menu-config.sales$Customer.lookup=Customers</programlisting></para>
|
||||
<url-pattern>/api/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
</web-app></programlisting></para>
|
||||
<para>В элементах <sgmltag>context-param</sgmltag> задаются иницилизирующие параметры объекта <code>ServletContext</code> данного веб-приложения. Здесь определен параметр <literal>appPropertiesConfig</literal>, значением которого является список <link linkend="app_properties_files">файлов свойств приложения</link>.</para>
|
||||
<para>В элементах <sgmltag>context-param</sgmltag> задаются инициализирующие параметры объекта <code>ServletContext</code> данного веб-приложения. Здесь определен параметр <literal>appPropertiesConfig</literal>, значением которого является список <link linkend="app_properties_files">файлов свойств приложения</link>.</para>
|
||||
<para>В элементе <sgmltag>listener</sgmltag> задается класс слушателя, реализующего интерфейс <code>ServletContextListener</code>. В блоке <structname>Middleware</structname> CUBA-приложения в качестве слушателя должен использоваться класс <code>AppContextLoader</code>, выполняющий инициализацию <code>
|
||||
<link linkend="appContext">AppContext</link>
|
||||
</code>.</para>
|
||||
@ -773,7 +773,7 @@ menu-config.sales$Customer.lookup=Customers</programlisting></para>
|
||||
<term>cuba.confDir</term>
|
||||
<listitem>
|
||||
<para>Конфигурационный параметр, задающий расположение <link linkend="conf_dir">каталога конфигурации</link> данного <link linkend="app_tiers">блока приложения</link>.</para>
|
||||
<para>Значение по умолчанию для блоков <structname>Middleware</structname>, <structname>Web Client</structname>, <structname>Web Portal</structname>: <literal>${catalina.home}/conf/${<link linkend="cuba.webContextName">cuba.webContextName</link>}</literal>, что в случае стандартного развертывания в <application>Tomcat</application> означает расположение внутри каталога <filename>tomcat/conf</filename> в подкаталоге с именем текущего веб-приложения, например <filename>tomcat/conf/app-core</filename>.</para>
|
||||
<para>Значение по умолчанию для блоков <structname>Middleware</structname>, <structname>Web Client</structname>, <structname>Web Portal</structname>: <literal>${catalina.home}/conf/${<link linkend="cuba.webContextName">cuba.webContextName</link>}</literal>, что в случае стандартного развертывания в <application>Tomcat</application> означает расположение внутри каталога <filename>tomcat/conf</filename> в подкаталоге с именем текущего веб-приложения, например, <filename>tomcat/conf/app-core</filename>.</para>
|
||||
<para>Значение по умолчанию для блока <structname>Desktop Client</structname>: <literal>${<link linkend="cuba.desktop.home">cuba.desktop.home</link>}/conf</literal>. </para>
|
||||
<para>Интерфейс: <code>GlobalConfig</code></para>
|
||||
<para>Используется во всех стандартных <link linkend="app_tiers">блоках</link>.</para>
|
||||
@ -802,7 +802,7 @@ menu-config.sales$Customer.lookup=Customers</programlisting></para>
|
||||
<term>cuba.dataDir</term>
|
||||
<listitem>
|
||||
<para>Конфигурационный параметр, задающий расположение <link linkend="work_dir">рабочего каталога</link> данного <link linkend="app_tiers">блока приложения</link>.</para>
|
||||
<para>Значение по умолчанию для блоков <structname>Middleware</structname>, <structname>Web Client</structname>, <structname>Web Portal</structname>: <literal>${catalina.home}/work/${<link linkend="cuba.webContextName">cuba.webContextName</link>}</literal>, что в случае стандартного развертывания в <application>Tomcat</application> означает расположение внутри каталога <filename>tomcat/work</filename> в подкаталоге с именем текущего веб-приложения, например <filename>tomcat/work/app-core</filename>.</para>
|
||||
<para>Значение по умолчанию для блоков <structname>Middleware</structname>, <structname>Web Client</structname>, <structname>Web Portal</structname>: <literal>${catalina.home}/work/${<link linkend="cuba.webContextName">cuba.webContextName</link>}</literal>, что в случае стандартного развертывания в <application>Tomcat</application> означает расположение внутри каталога <filename>tomcat/work</filename> в подкаталоге с именем текущего веб-приложения, например, <filename>tomcat/work/app-core</filename>.</para>
|
||||
<para>Значение по умолчанию для блока <structname>Desktop Client</structname>: <literal>${<link linkend="cuba.desktop.home">cuba.desktop.home</link>}/work</literal>. </para>
|
||||
<para>Интерфейс: <code>GlobalConfig</code></para>
|
||||
<para>Используется во всех стандартных <link linkend="app_tiers">блоках</link>.</para>
|
||||
@ -829,7 +829,7 @@ menu-config.sales$Customer.lookup=Customers</programlisting></para>
|
||||
<term>cuba.defaultQueryTimeoutSec</term>
|
||||
<listitem>
|
||||
<para>Задает <link linkend="transaction_timeout">таймаут транзакции</link> по умолчанию.</para>
|
||||
<para>Значение по умолчанию: <literal>0</literal>, означает что таймаут отсутствует.</para>
|
||||
<para>Значение по умолчанию: <literal>0</literal>, означает, что таймаут отсутствует.</para>
|
||||
<para>Интерфейс: <code>ServerConfig</code></para>
|
||||
<para>Используется в блоке <structname>Middleware</structname>.</para>
|
||||
</listitem>
|
||||
@ -932,8 +932,8 @@ menu-config.sales$Customer.lookup=Customers</programlisting></para>
|
||||
<term>cuba.gui.useSaveConfirmation</term>
|
||||
<listitem>
|
||||
<para>Определяет форму диалога, возникающего при попытке закрытия <link linkend="screens">экрана</link>, имеющего несохраненные изменения в источниках данных.</para>
|
||||
<para>Значение <literal>true</literal> задает форму с тремя варантами выбора: сохранить изменения, не сохранять, либо не закрывать экран.</para>
|
||||
<para>Значение <literal>false</literal> задает форму с двумя варантами: закрыть экран не сохраняя изменений, либо не закрывать экран.</para>
|
||||
<para>Значение <literal>true</literal> задает форму с тремя вариантами выбора: сохранить изменения, не сохранять, либо не закрывать экран.</para>
|
||||
<para>Значение <literal>false</literal> задает форму с двумя вариантами: закрыть экран не сохраняя изменений, либо не закрывать экран.</para>
|
||||
<para>Значение по умолчанию: <code>true</code></para>
|
||||
<para>Интерфейс: <code>ClientConfig</code></para>
|
||||
<para>Используется в блоках <structname>Web Client</structname> и <structname>Desktop Client</structname>.</para>
|
||||
@ -1108,7 +1108,7 @@ menu-config.sales$Customer.lookup=Customers</programlisting></para>
|
||||
<varlistentry id="cuba.portal.anonymousUserLogin">
|
||||
<term>cuba.portal.anonymousUserLogin</term>
|
||||
<listitem>
|
||||
<para>Логин пользователя системы, который используется для создания аниномной пользовательской сессии в блоке <structname>Web Portal</structname>. </para>
|
||||
<para>Логин пользователя системы, который используется для создания анонимной пользовательской сессии в блоке <structname>Web Portal</structname>. </para>
|
||||
<para>Пользователь с таким логином должен быть создан в подсистеме безопасности, и ему должны быть назначены соответствующие права. Пароль пользователя игнорируется, так как анонимная сессия портала создается методом <code>
|
||||
<link linkend="login">loginTrusted()</link>
|
||||
</code> с передачей пароля, указанного в свойстве <property>
|
||||
@ -1167,7 +1167,7 @@ menu-config.sales$Customer.lookup=Customers</programlisting></para>
|
||||
<term>cuba.tempDir</term>
|
||||
<listitem>
|
||||
<para>Конфигурационный параметр, задающий расположение <link linkend="temp_dir">временного каталога</link> данного <link linkend="app_tiers">блока приложения</link>.</para>
|
||||
<para>Значение по умолчанию для блоков <structname>Middleware</structname>, <structname>Web Client</structname>, <structname>Web Portal</structname>: <literal>${catalina.home}/temp/${<link linkend="cuba.webContextName">cuba.webContextName</link>}</literal>, что в случае стандартного развертывания в <application>Tomcat</application> означает расположение внутри каталога <filename>tomcat/temp</filename> в подкаталоге с именем текущего веб-приложения, например <filename>tomcat/temp/app-core</filename>.</para>
|
||||
<para>Значение по умолчанию для блоков <structname>Middleware</structname>, <structname>Web Client</structname>, <structname>Web Portal</structname>: <literal>${catalina.home}/temp/${<link linkend="cuba.webContextName">cuba.webContextName</link>}</literal>, что в случае стандартного развертывания в <application>Tomcat</application> означает расположение внутри каталога <filename>tomcat/temp</filename> в подкаталоге с именем текущего веб-приложения, например, <filename>tomcat/temp/app-core</filename>.</para>
|
||||
<para>Значение по умолчанию для блока <structname>Desktop Client</structname>: <literal>${<link linkend="cuba.desktop.home">cuba.desktop.home</link>}/temp</literal>. </para>
|
||||
<para>Интерфейс: <code>GlobalConfig</code></para>
|
||||
<para>Используется во всех стандартных <link linkend="app_tiers">блоках</link>.</para>
|
||||
|
Loading…
Reference in New Issue
Block a user