view dist/biotopes/doc/article.txt @ 1:548a93c24e55

Tema 0.1jk - Javakonkurs edition (imported from CVS).
author Mikhail Kryshen <mikhail@kryshen.net>
date Thu, 14 Dec 2006 23:22:05 +0300
parents
children
line source
1 * Преобразование базы данных в XML-формат электронной библиотеки.
3 Для решения задачи преобразования базы данных "Местообитания Восточной
4 Фенноскандии" из формата Microsoft Access в XML-формат электронной
5 библиотеки КарНЦ РАН была разработана программная система DbReader.
7 Программа DbReader является универсальным средством для представления
8 информации из баз данных в текстовых форматах. Программа обрабатывает
9 заданные шаблоны текстовых файлов и заменяет найденные в них
10 инструкции на результаты их выполнения. Различные инструкции позволяют
11 формировать SQL-запросы, выполнять их и обрабатывать полученные
12 данные.
15 * Формат инструкций:
17 <%<список_функций>{:|\}<данные>%>
18 где
20 <список_функций> - список имен функций, разделенных пробелами.
21 Может быть пустым.
22 <данные> - данные, передаваемые функции.
25 * Формат данных:
27 [<список_аргументов>][<текст>]
28 где
30 <список_аргументов> - список аргументов функции, разделенных пробелами.
31 Может быть пустым.
32 <текст> - текст, передаваемый функции без разбиения на аргументы.
33 Может быть пустым. Количество аргументов, после которого следует
34 текст, зависит от функции.
36 Разделитель между списком функций и данными определяет, как должны
37 обрабатываться данные функции:
38 : - рекурсивная обработка,
39 \ - передать без обработки.
41 Если в списке функций задано две и более функции, они выполняются,
42 начиная с последней, так что каждая функция получает в качестве данных
43 результат выполнения следующей функции.
45 Каждая функция имеет код возврата - целое число. Код возврата
46 инструкции - код возврата первой в списке функции. Код возврата,
47 получаемый при обработке текста - сумма кодов возврата обработанных
48 инструкций.
50 Вместо скобок '<', '>' можно использовать скобки '[', ']'.
53 * Реализованные функции:
55 Функция: set
56 Аргументы: <имя>
57 Текст: <значение>
58 Действие: устанавливает значение переменной <имя>
59 Результат: <имя>
60 Код возврата: 1
62 Функция: get
63 Аргументы: <имя>
64 Результат: значение переменной <имя>.
65 Код возврата: 1, если значение переменной было установлено, 0 - иначе.
67 Функция: prepare
68 Аргументы: <имя>
69 Текст: <запрос>
70 Действие: Подготавливает SQL-запрос <запрос> для выполнения,
71 записывает подготовленный запрос в переменную <имя>.
72 Результат: <имя>
73 Код возврата: 1
75 Функция: query
76 Аргументы: <имя_запроса> <шаблон> <парам1> ... <парамN>
77 Действие: Выполняет запрос с параметрами, подготовленный с помощью
78 функции prepare. Значения параметров подставляются в
79 запрос вместо символа '?'. Значения полей ответа будут
80 записаны, как переменные шаблона <шаблон>. При обработки
81 шаблона <шаблон> также определяется переменная NUMBER,
82 содержащая номер текущей строки ответа. Переменные,
83 определенные в вызывающем шаблоне, доступны из шаблона
84 <шаблон> по имени SUPER.<имя_переменной>.
86 Результат: результат обработки шаблона <шаблон> для каждой строки
87 ответа.
88 Код возврата: количество полученных строк ответа.
90 Функция: optional
91 Текст: <данные>
92 Результат: <данные>, если при обработке данных был получен
93 код возврата отличный от 0, иначе - пустая строка.
94 Код возврата: 1, если результат - пустая строка, 0 - иначе.
96 Функция: image
97 Аргументы: <исх_файл> <кон_файл> <формат> [<макс_ширина> [<макс_высота>]]
98 Действие: Загружает изображение из файла <исх_файл> (путь определяется
99 относительно конфигурационного параметра "resource_base") и
100 преобразует его в указанный формат, сохраняя результат в
101 <кон_файл>. Если заданы максимальная высота и ширина, большие
102 изображения будут уменьшены.
103 Результат: <кон_файл> при успешном выполнении, пустая строка - иначе.
104 Код возврата: 1 при успешном выполнении, 0 - иначе.
106 Функция: copy
107 Аргументы: <исх_файл> <кон_файл>
108 Действие: Копирует файл <исх_файл> в файл <кон_файл>
109 (путь <исх_файл> определяется относительно
110 конфигурационного параметра "resource_base").
111 Результат: <кон_файл> при успешном выполнении, пустая строка - иначе.
112 Код возврата: 1 при успешном выполнении, 0 - иначе.
114 Функция: write
115 Аргументы: <имя_файла>
116 Текст: <данные>
117 Действие: Записывает <данные> в файл <исх_файл>.
118 Результат: <кон_файл> при успешном выполнении, пустая строка - иначе.
119 Код возврата: 1 при успешном выполнении, 0 - иначе.
121 Функция: read
122 Текст: <имя_файла>
123 Действие: Читает файл <имя_файла>.
124 Результат: прочитанные данные при успешном выполнении, пустая
125 строка - иначе.
126 Код возврата: 1 при успешном выполнении, 0 - иначе.
128 Функция: include
129 Текст: <имя_файла>
130 Действие: включает шаблон из файла <имя_файла>.
131 Результат: результат обработки шаблона.
132 Код возврата: код возврата, полученный при обработке шаблона.
134 Функция: !
135 Текст: <данные>
136 Действие: нет.
137 Результат: нет.
138 Код возврата: код возврата, полученный при обработке текста данных.
140 Функция: replace
141 Аргументы: <стр1> <стр2>
142 Текст: <данные>
143 Результат: данные, с замененными вхождениями подстроки <стр1>
144 на <стр2>.
145 Код возврата: код возврата, полученный при обработке текста данных.
147 Функция: xml_escape
148 Текст: <данные>
149 Результат: текст <данные>, в котором символы
150 '&', '<', '>', '`', '\' заменены на соответствующие
151 сущности XML.
152 Код возврата: код возврата, полученный при обработке текста данных.
154 Функция: xml_cdata
155 Текст: <данные>
156 Результат: данные в виде блока XML CDATA.
157 Код возврата: код возврата, полученный при обработке текста данных.
159 Система DbReader расширяема: возможно добавление в систему новых
160 функций, реализованных в виде классов на языке Java.
163 * Применение системы DbReader для преобразования базы данных
164 "Местообитания Восточной Фенноскандии" из формата Microsoft Access в
165 XML-формат электронной библиотеки КарНЦ РАН
167 Для преобразования используются две таблицы базы данных "Местообитания
168 Восточной Фенноскандии" (перечислены только используемые поля):
170 biotopelist (code, rangcode, rusname, engname, descript, geobotdescr,
171 contributors, descrdate)
173 code - счетчик, ключевое поле;
174 rangcode - поле в формате ABBCCDDEE, где А, BB, CC, DD, ЕЕ - коды
175 класса, подклассов и растения;
176 rusname, engname, descript, geobotdescr - текстовые поля;
177 descrdate - дата.
179 photos (biotope, photo, authphoto)
181 biotope - число, указывает на code в biotopelist;
182 photo - имя файла фотографии;
183 authphoto - текст.
185 Требуется сгенерировать xml-файл для каждой записи в biotopelist, файл
186 со списком классов, файл со списком растений, полноразмерные и
187 уменьшенные версии каждой фотографии.
189 Для генерации xml-файлов с описаниями биотопов использовался следующий
190 шаблон DbReader (файл biotope.template):
192 ----------------------------------------------------------------------
193 <?xml version="1.0" encoding="ISO-8859-5"?>
194 <!DOCTYPE описание_вида SYSTEM "brief.dtd">
195 <!-- rangcode: <%xml_escape get\rangcode%> -->
196 <описание_вида show="0">
197 <рисунки display="0">
198 <%optional:<карта_распространения номер="1"
199 file="<%xml_escape image:maps/<%get\rangcode%>.gif maps/<%get\code%>.png png%>"/>%>
200 <%query:photo_sql [%\<%include\photo.template%>%] <%get\code%>%>
201 </рисунки>
202 <название><%xml_escape get\rusname%></название>
203 <класс><%xml_escape get\class0%></класс>
204 <подкласс1><%xml_escape get\class1%></подкласс1>
205 <подкласс2><%xml_escape get\class2%></подкласс2>
206 <подкласс3><%xml_escape get\class3%></подкласс3>
207 <краткая_характеристика rows="3"><%xml_cdata get\descript%></краткая_характеристика>
208 <пример_описания rows="3"><%xml_cdata get\geobotdescr%></пример_описания>
209 <авторы_описания><%xml_escape get\contributors%></авторы_описания>
210 </описание_вида>
211 ----------------------------------------------------------------------
213 Соответствующий SQL-запрос, при выполнении которого устанавливаются
214 значения переменных шаблона rangcode, rusname, class0, class1, class2,
215 class3, descript, geobotdescr и contributors (файл biotope.sql):
217 ----------------------------------------------------------------------
218 SELECT t1.*,
220 (SELECT t2.rusname FROM biotopelist AS t2
221 WHERE Left(t2.rangcode, 1) = Left(t1.rangcode, 1)
222 AND Right(t2.rangcode, 8) = '00000000'
223 AND Right(t1.rangcode, 8) <> '00000000') AS class0,
225 (SELECT t2.rusname FROM biotopelist AS t2
226 WHERE Left(t2.rangcode, 3) = Left(t1.rangcode, 3)
227 AND Right(t2.rangcode, 6) = '000000'
228 AND Right(t1.rangcode, 6) <> '000000') AS class1,
230 (SELECT t2.rusname FROM biotopelist AS t2
231 WHERE Left(t2.rangcode, 5) = Left(t1.rangcode, 5)
232 AND Right(t2.rangcode, 4) = '0000'
233 AND Right(t1.rangcode, 4) <> '0000') AS class2,
235 (SELECT t2.rusname FROM biotopelist AS t2
236 WHERE Left(t2.rangcode, 7) = Left(t1.rangcode, 7)
237 AND Right(t2.rangcode, 2) = '00'
238 AND Right(t1.rangcode, 2) <> '00') AS class3
240 FROM biotopelist AS t1
241 WHERE rusname
242 ----------------------------------------------------------------------
244 Шаблон biotope.template содержит инструкцию <%include\photo.template%>,
245 включающую шаблон описания фотографии (файл photo.template):
247 ----------------------------------------------------------------------
248 <фотография num="<%xml_escape get\NUMBER%>"
249 <%optional:автор="<%xml_escape get\authphoto%>" %>text=""
250 file="<%xml_escape image:biotopephotos/<%get\photo%> images/<%get\SUPER.code%>_<%get\NUMBER%>.jpg jpg 300 300%>"
251 big="<%xml_escape copy:biotopephotos/<%get\photo%> images/big/<%get\SUPER.code%>_<%get\NUMBER%>.jpg%>"/>
252 ----------------------------------------------------------------------
254 Соответствующий SQL-запрос для получения описания фотографий
255 (photo.sql):
257 ----------------------------------------------------------------------
258 SELECT * from photos WHERE biotope = ?
259 ----------------------------------------------------------------------
261 Шаблон, генерирующий список классов (файл classes.template):
263 ----------------------------------------------------------------------
264 <?xml version="1.0" encoding="ISO-8859-5"?>
265 <классификация><%query:class_sql [%\
266 <!-- rangcode: <%xml_escape get\rangcode%> -->
267 <класс id="<%get\NUMBER%>"><%xml_escape get\rusname%></класс>%]%>
268 </классификация>
269 ----------------------------------------------------------------------
271 Соответствующий SQL-запрос (class.sql):
273 ----------------------------------------------------------------------
274 SELECT t1.*
275 FROM biotopelist AS t1
276 WHERE rusname AND Right(t1.rangcode, 8) = '00000000'
277 AND EXISTS
278 (SELECT NULL FROM biotopelist AS t2
279 WHERE Left(t2.rangcode, 1) = Left(t1.rangcode, 1)
280 AND Right(t2.rangcode, 8) <> '00000000')
281 ----------------------------------------------------------------------
283 Шаблон, генерирующий список растений (файл plants.template):
285 ----------------------------------------------------------------------
286 <?xml version="1.0" encoding="ISO-8859-5"?>
287 <растения><%query:plant_sql [%\
288 <!-- rangcode: <%xml_escape get\rangcode%> -->
289 <растение><%xml_escape get\rusname%></растение>%]%>
290 </растения>
291 ----------------------------------------------------------------------
293 Соответствующий SQL-запрос (plant.sql):
295 ----------------------------------------------------------------------
296 SELECT t1.*
297 FROM biotopelist AS t1
298 WHERE rusname AND Right(t1.rangcode, 2) <> '00'
299 ----------------------------------------------------------------------
301 Система DbReader начинает работу с обработки шаблона index.template,
302 который содержит вызовы перечисленных выше SQL-запросов и включения
303 шаблонов:
305 ----------------------------------------------------------------------
306 <%!:
307 <%prepare:biotope_sql <%read\biotope.sql%>%>
308 <%prepare:photo_sql <%read\photo.sql%>%>
309 <%prepare:class_sql <%read\class.sql%>%>
310 <%prepare:plant_sql <%read\plant.sql%>%>
312 <%query:biotope_sql [%\<%write:<%get\code%>.xml <%include\biotope.template%>%> %]%>
314 <%write:classes.xml <%include\classes.template%>%>
315 <%write:plants.xml <%include\plants.template%>%>
316 %>
317 ----------------------------------------------------------------------
319 Пример сгенерированного XML-файла:
321 ----------------------------------------------------------------------
322 <?xml version="1.0" encoding="ISO-8859-5"?>
323 <!DOCTYPE описание_вида SYSTEM "brief.dtd">
324 <!-- rangcode: E04020302 -->
325 <описание_вида show="0">
326 <рисунки display="0">
327 <фотография num="1" автор="Крышень А.М." text=""
328 file="images/3_1.jpg"
329 big="images/big/3_1.jpg"/>
330 <фотография num="2" автор="Крышень А.М." text=""
331 file="images/3_2.jpg"
332 big="images/big/3_2.jpg"/>
333 </рисунки>
334 <название>Betula sp. - Avenella flexuosa - Polytrichum commune</название>
335 <класс>E. Суходольные местообитания</класс>
336 <подкласс1>Автоморфные влажные</подкласс1>
337 <подкласс2></подкласс2>
338 <подкласс3></подкласс3>
339 <краткая_характеристика rows="3"><![CDATA[Развиваются на луговиковых вырубках лесов черничного типа. Через 5 - 7 лет после рубки порослевая береза выходит из яруса травянистых растений, ее влияние сказывается, в первую очередь, на влажности почвы.]]></краткая_характеристика>
340 <пример_описания rows="3"></пример_описания>
341 <авторы_описания></авторы_описания>
342 </описание_вида>
343 ----------------------------------------------------------------------
346 * Структура программы DbReader
348 Программа DbReader написана на языке программирования Java и состоит
349 из следующих основных классов:
351 ru.karrc.dbreader.DbReader: cодержит точку входа программы. Загружает
352 конфигурацию, устанавливает соединение с источником данных с помощью
353 библиотеки JDBC, запускает обработку основного шаблона.
355 ru.karrc.dbreader.TemplateParser: осуществляет разбор шаблона,
356 обработку инструкций и вызов функций.
358 ru.karrc.dbreader.Function: абстрактный класс. Реализации всех функций
359 DbReader наследуют этот класс.
361 ru.karrc.dbreader.FunctionDataParser: обработчик данных
362 функции. Посволяет получить список аргументов и текст, передаваемый
363 функции. При необходимости вызывает рекурсивную обработку данных с
364 помощью TemplateParser.
366 ru.karrc.dbreader.Functions: содержит реализации функций в виде
367 анонимных классов, наследующих Function.
369 ru.karrc.dbreader.TemplateParser: исключение, выбрасываемое в случае
370 возникновения ошибки при обработке шаблона.
372 Кроме того, реализовано несколько впомогательных классов, которые
373 используются в реализациях функций системы.
376 * Метрики реализованной программной системы.
378 Количество файлов исходного кода: 8,
379 Количество Java-классов (включая анонимные): 27,
380 Общее количество строк исходного текста: 1311,
381 Количество строк кода (исключая пустые строки и комментарии): 812,
382 Количество строк комментариев: 180.
385 * Заключение
387 Автором была разработана программная система DbReader, которая
388 является расширяемым и универсальным средством для представления
389 информации из баз данных в текстовых форматах. С помощью системы
390 DbReader база данных "Местообитания Восточной Фенноскандии" была
391 переведена в XML-формат электронной библиотеки КарНЦ РАН.