Mercurial > hg > tema
changeset 1:548a93c24e55 release_0_1jk
Tema 0.1jk - Javakonkurs edition (imported from CVS).
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/TODO Thu Dec 14 23:22:05 2006 +0300 1.3 @@ -0,0 +1,1 @@ 1.4 +if, <, >, =, +, -, *, /
2.1 --- a/build.xml Tue May 16 18:04:09 2006 +0400 2.2 +++ b/build.xml Thu Dec 14 23:22:05 2006 +0300 2.3 @@ -5,6 +5,7 @@ 2.4 <property name="build" value="build"/> 2.5 <property name="dist" value="dist"/> 2.6 <property name="res" value="res"/> 2.7 + <property name="doc" value="doc"/> 2.8 <property name="jar_file" value="tema.jar"/> 2.9 2.10 <target name="init"> 2.11 @@ -14,20 +15,30 @@ 2.12 2.13 <target name="compile" depends="init"> 2.14 <javac srcdir="${src}" destdir="${build}" 2.15 - deprecation="on" optimize="on" debug="on"/> 2.16 + deprecation="on" optimize="on" debug="on"> 2.17 + <!-- <compilerarg value="-Xlint:unchecked"/> --> 2.18 + </javac> 2.19 </target> 2.20 2.21 <target name="dist" depends="compile"> 2.22 <jar jarfile="${dist}/${jar_file}" manifest="${src}/Manifest.mf"> 2.23 <fileset dir="${build}" includes="**/*.class"/> 2.24 + <fileset dir="${res}" includes="**/*"/> 2.25 </jar> 2.26 - </target> 2.27 + </target> 2.28 2.29 + <target name="javadoc" depends="init"> 2.30 + <javadoc destdir="${doc}/api" sourcepath="${src}" 2.31 + packagenames="kryshen.tema.*"> 2.32 + </javadoc> 2.33 + </target> 2.34 + 2.35 <target name="clean"> 2.36 <delete> 2.37 <fileset dir="${build}" includes="**/*.class"/> 2.38 </delete> 2.39 <delete file="${dist}/${jar_file}"/> 2.40 + <delete dir="${doc}/api"/> 2.41 </target> 2.42 2.43 </project>
3.1 --- a/dist/biotopes/biotope.template Tue May 16 18:04:09 2006 +0400 3.2 +++ b/dist/biotopes/biotope.template Thu Dec 14 23:22:05 2006 +0300 3.3 @@ -1,17 +1,17 @@ 3.4 <?xml version="1.0" encoding="ISO-8859-5"?> 3.5 <!DOCTYPE чъьАпщьу_рьтп SYSTEM "brief.dtd"> 3.6 -<!-- rangcode: <%xml_escape get\rangcode%> --> 3.7 +<!-- rangcode: <%xml_escape db\rangcode%> --> 3.8 <чъьАпщьу_рьтп show="0"> 3.9 <ЮьАЦщзь display="0"> 3.10 - <%optional:<зпЮБп_ЮпАъЮчАБЮпщущьО щчэуЮ="1" file="<%xml_escape image:maps/<%get\rangcode%>.gif maps/<%get\code%>.png png%>"/>%> 3.11 + <%optional:<зпЮБп_ЮпАъЮчАБЮпщущьО щчэуЮ="1" file="<%xml_escape image:maps/<%db\rangcode%>.gif maps/<%db\code%>.png png%>"/>%> 3.12 <%query:photo_sql [%\<%include\photo.template%>%] <%get\code%>%> 3.13 </ЮьАЦщзь> 3.14 - <щпврпщьу><%xml_escape get\rusname%></щпврпщьу> 3.15 - <зшпАА><%xml_escape get\class0%></зшпАА> 3.16 - <ъчтзшпАА1><%xml_escape get\class1%></ъчтзшпАА1> 3.17 - <ъчтзшпАА2><%xml_escape get\class2%></ъчтзшпАА2> 3.18 - <ъчтзшпАА3><%xml_escape get\class3%></ъчтзшпАА3> 3.19 - <зЮпБзпО_ЕпЮпзБуЮьАБьзп rows="3"><%xml_cdata get\descript%></зЮпБзпО_ЕпЮпзБуЮьАБьзп> 3.20 - <ъЮьэуЮ_чъьАпщьО rows="3"><%xml_cdata get\geobotdescr%></ъЮьэуЮ_чъьАпщьО> 3.21 - <прБчЮК_чъьАпщьО><%xml_escape get\contributors%></прБчЮК_чъьАпщьО> 3.22 + <щпврпщьу><%xml_escape db\rusname%></щпврпщьу> 3.23 + <зшпАА><%xml_escape db\class0%></зшпАА> 3.24 + <ъчтзшпАА1><%xml_escape db\class1%></ъчтзшпАА1> 3.25 + <ъчтзшпАА2><%xml_escape db\class2%></ъчтзшпАА2> 3.26 + <ъчтзшпАА3><%xml_escape db\class3%></ъчтзшпАА3> 3.27 + <зЮпБзпО_ЕпЮпзБуЮьАБьзп rows="3"><%xml_cdata db\descript%></зЮпБзпО_ЕпЮпзБуЮьАБьзп> 3.28 + <ъЮьэуЮ_чъьАпщьО rows="3"><%xml_cdata db\geobotdescr%></ъЮьэуЮ_чъьАпщьО> 3.29 + <прБчЮК_чъьАпщьО><%xml_escape db\contributors%></прБчЮК_чъьАпщьО> 3.30 </чъьАпщьу_рьтп>
4.1 --- a/dist/biotopes/classes.template Tue May 16 18:04:09 2006 +0400 4.2 +++ b/dist/biotopes/classes.template Thu Dec 14 23:22:05 2006 +0300 4.3 @@ -1,5 +1,5 @@ 4.4 <?xml version="1.0" encoding="ISO-8859-5"?> 4.5 <зшпААьДьзпФьО><%query:class_sql [%\ 4.6 <!-- rangcode: <%xml_escape get\rangcode%> --> 4.7 - <зшпАА id="<%get\NUMBER%>"><%xml_escape get\rusname%></зшпАА>%]%> 4.8 + <зшпАА id="<%get\NUMBER%>"><%xml_escape db\rusname%></зшпАА>%]%> 4.9 </зшпААьДьзпФьО>
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/dist/biotopes/doc/article.txt Thu Dec 14 23:22:05 2006 +0300 5.3 @@ -0,0 +1,391 @@ 5.4 +* Преобразование базы данных в XML-формат электронной библиотеки. 5.5 + 5.6 +Для решения задачи преобразования базы данных "Местообитания Восточной 5.7 +Фенноскандии" из формата Microsoft Access в XML-формат электронной 5.8 +библиотеки КарНЦ РАН была разработана программная система DbReader. 5.9 + 5.10 +Программа DbReader является универсальным средством для представления 5.11 +информации из баз данных в текстовых форматах. Программа обрабатывает 5.12 +заданные шаблоны текстовых файлов и заменяет найденные в них 5.13 +инструкции на результаты их выполнения. Различные инструкции позволяют 5.14 +формировать SQL-запросы, выполнять их и обрабатывать полученные 5.15 +данные. 5.16 + 5.17 + 5.18 +* Формат инструкций: 5.19 + 5.20 + <%<список_функций>{:|\}<данные>%> 5.21 + где 5.22 + 5.23 +<список_функций> - список имен функций, разделенных пробелами. 5.24 + Может быть пустым. 5.25 +<данные> - данные, передаваемые функции. 5.26 + 5.27 + 5.28 +* Формат данных: 5.29 + 5.30 + [<список_аргументов>][<текст>] 5.31 + где 5.32 + 5.33 +<список_аргументов> - список аргументов функции, разделенных пробелами. 5.34 + Может быть пустым. 5.35 +<текст> - текст, передаваемый функции без разбиения на аргументы. 5.36 + Может быть пустым. Количество аргументов, после которого следует 5.37 + текст, зависит от функции. 5.38 + 5.39 +Разделитель между списком функций и данными определяет, как должны 5.40 +обрабатываться данные функции: 5.41 +: - рекурсивная обработка, 5.42 +\ - передать без обработки. 5.43 + 5.44 +Если в списке функций задано две и более функции, они выполняются, 5.45 +начиная с последней, так что каждая функция получает в качестве данных 5.46 +результат выполнения следующей функции. 5.47 + 5.48 +Каждая функция имеет код возврата - целое число. Код возврата 5.49 +инструкции - код возврата первой в списке функции. Код возврата, 5.50 +получаемый при обработке текста - сумма кодов возврата обработанных 5.51 +инструкций. 5.52 + 5.53 +Вместо скобок '<', '>' можно использовать скобки '[', ']'. 5.54 + 5.55 + 5.56 +* Реализованные функции: 5.57 + 5.58 +Функция: set 5.59 +Аргументы: <имя> 5.60 +Текст: <значение> 5.61 +Действие: устанавливает значение переменной <имя> 5.62 +Результат: <имя> 5.63 +Код возврата: 1 5.64 + 5.65 +Функция: get 5.66 +Аргументы: <имя> 5.67 +Результат: значение переменной <имя>. 5.68 +Код возврата: 1, если значение переменной было установлено, 0 - иначе. 5.69 + 5.70 +Функция: prepare 5.71 +Аргументы: <имя> 5.72 +Текст: <запрос> 5.73 +Действие: Подготавливает SQL-запрос <запрос> для выполнения, 5.74 + записывает подготовленный запрос в переменную <имя>. 5.75 +Результат: <имя> 5.76 +Код возврата: 1 5.77 + 5.78 +Функция: query 5.79 +Аргументы: <имя_запроса> <шаблон> <парам1> ... <парамN> 5.80 +Действие: Выполняет запрос с параметрами, подготовленный с помощью 5.81 + функции prepare. Значения параметров подставляются в 5.82 + запрос вместо символа '?'. Значения полей ответа будут 5.83 + записаны, как переменные шаблона <шаблон>. При обработки 5.84 + шаблона <шаблон> также определяется переменная NUMBER, 5.85 + содержащая номер текущей строки ответа. Переменные, 5.86 + определенные в вызывающем шаблоне, доступны из шаблона 5.87 + <шаблон> по имени SUPER.<имя_переменной>. 5.88 + 5.89 +Результат: результат обработки шаблона <шаблон> для каждой строки 5.90 + ответа. 5.91 +Код возврата: количество полученных строк ответа. 5.92 + 5.93 +Функция: optional 5.94 +Текст: <данные> 5.95 +Результат: <данные>, если при обработке данных был получен 5.96 + код возврата отличный от 0, иначе - пустая строка. 5.97 +Код возврата: 1, если результат - пустая строка, 0 - иначе. 5.98 + 5.99 +Функция: image 5.100 +Аргументы: <исх_файл> <кон_файл> <формат> [<макс_ширина> [<макс_высота>]] 5.101 +Действие: Загружает изображение из файла <исх_файл> (путь определяется 5.102 + относительно конфигурационного параметра "resource_base") и 5.103 + преобразует его в указанный формат, сохраняя результат в 5.104 + <кон_файл>. Если заданы максимальная высота и ширина, большие 5.105 + изображения будут уменьшены. 5.106 +Результат: <кон_файл> при успешном выполнении, пустая строка - иначе. 5.107 +Код возврата: 1 при успешном выполнении, 0 - иначе. 5.108 + 5.109 +Функция: copy 5.110 +Аргументы: <исх_файл> <кон_файл> 5.111 +Действие: Копирует файл <исх_файл> в файл <кон_файл> 5.112 + (путь <исх_файл> определяется относительно 5.113 + конфигурационного параметра "resource_base"). 5.114 +Результат: <кон_файл> при успешном выполнении, пустая строка - иначе. 5.115 +Код возврата: 1 при успешном выполнении, 0 - иначе. 5.116 + 5.117 +Функция: write 5.118 +Аргументы: <имя_файла> 5.119 +Текст: <данные> 5.120 +Действие: Записывает <данные> в файл <исх_файл>. 5.121 +Результат: <кон_файл> при успешном выполнении, пустая строка - иначе. 5.122 +Код возврата: 1 при успешном выполнении, 0 - иначе. 5.123 + 5.124 +Функция: read 5.125 +Текст: <имя_файла> 5.126 +Действие: Читает файл <имя_файла>. 5.127 +Результат: прочитанные данные при успешном выполнении, пустая 5.128 + строка - иначе. 5.129 +Код возврата: 1 при успешном выполнении, 0 - иначе. 5.130 + 5.131 +Функция: include 5.132 +Текст: <имя_файла> 5.133 +Действие: включает шаблон из файла <имя_файла>. 5.134 +Результат: результат обработки шаблона. 5.135 +Код возврата: код возврата, полученный при обработке шаблона. 5.136 + 5.137 +Функция: ! 5.138 +Текст: <данные> 5.139 +Действие: нет. 5.140 +Результат: нет. 5.141 +Код возврата: код возврата, полученный при обработке текста данных. 5.142 + 5.143 +Функция: replace 5.144 +Аргументы: <стр1> <стр2> 5.145 +Текст: <данные> 5.146 +Результат: данные, с замененными вхождениями подстроки <стр1> 5.147 + на <стр2>. 5.148 +Код возврата: код возврата, полученный при обработке текста данных. 5.149 + 5.150 +Функция: xml_escape 5.151 +Текст: <данные> 5.152 +Результат: текст <данные>, в котором символы 5.153 + '&', '<', '>', '`', '\' заменены на соответствующие 5.154 + сущности XML. 5.155 +Код возврата: код возврата, полученный при обработке текста данных. 5.156 + 5.157 +Функция: xml_cdata 5.158 +Текст: <данные> 5.159 +Результат: данные в виде блока XML CDATA. 5.160 +Код возврата: код возврата, полученный при обработке текста данных. 5.161 + 5.162 +Система DbReader расширяема: возможно добавление в систему новых 5.163 +функций, реализованных в виде классов на языке Java. 5.164 + 5.165 + 5.166 +* Применение системы DbReader для преобразования базы данных 5.167 + "Местообитания Восточной Фенноскандии" из формата Microsoft Access в 5.168 + XML-формат электронной библиотеки КарНЦ РАН 5.169 + 5.170 +Для преобразования используются две таблицы базы данных "Местообитания 5.171 +Восточной Фенноскандии" (перечислены только используемые поля): 5.172 + 5.173 +biotopelist (code, rangcode, rusname, engname, descript, geobotdescr, 5.174 + contributors, descrdate) 5.175 + 5.176 + code - счетчик, ключевое поле; 5.177 + rangcode - поле в формате ABBCCDDEE, где А, BB, CC, DD, ЕЕ - коды 5.178 + класса, подклассов и растения; 5.179 + rusname, engname, descript, geobotdescr - текстовые поля; 5.180 + descrdate - дата. 5.181 + 5.182 +photos (biotope, photo, authphoto) 5.183 + 5.184 + biotope - число, указывает на code в biotopelist; 5.185 + photo - имя файла фотографии; 5.186 + authphoto - текст. 5.187 + 5.188 +Требуется сгенерировать xml-файл для каждой записи в biotopelist, файл 5.189 +со списком классов, файл со списком растений, полноразмерные и 5.190 +уменьшенные версии каждой фотографии. 5.191 + 5.192 +Для генерации xml-файлов с описаниями биотопов использовался следующий 5.193 +шаблон DbReader (файл biotope.template): 5.194 + 5.195 +---------------------------------------------------------------------- 5.196 +<?xml version="1.0" encoding="ISO-8859-5"?> 5.197 +<!DOCTYPE описание_вида SYSTEM "brief.dtd"> 5.198 +<!-- rangcode: <%xml_escape get\rangcode%> --> 5.199 +<описание_вида show="0"> 5.200 + <рисунки display="0"> 5.201 + <%optional:<карта_распространения номер="1" 5.202 + file="<%xml_escape image:maps/<%get\rangcode%>.gif maps/<%get\code%>.png png%>"/>%> 5.203 +<%query:photo_sql [%\<%include\photo.template%>%] <%get\code%>%> 5.204 + </рисунки> 5.205 + <название><%xml_escape get\rusname%></название> 5.206 + <класс><%xml_escape get\class0%></класс> 5.207 + <подкласс1><%xml_escape get\class1%></подкласс1> 5.208 + <подкласс2><%xml_escape get\class2%></подкласс2> 5.209 + <подкласс3><%xml_escape get\class3%></подкласс3> 5.210 + <краткая_характеристика rows="3"><%xml_cdata get\descript%></краткая_характеристика> 5.211 + <пример_описания rows="3"><%xml_cdata get\geobotdescr%></пример_описания> 5.212 + <авторы_описания><%xml_escape get\contributors%></авторы_описания> 5.213 +</описание_вида> 5.214 +---------------------------------------------------------------------- 5.215 + 5.216 +Соответствующий SQL-запрос, при выполнении которого устанавливаются 5.217 +значения переменных шаблона rangcode, rusname, class0, class1, class2, 5.218 +class3, descript, geobotdescr и contributors (файл biotope.sql): 5.219 + 5.220 +---------------------------------------------------------------------- 5.221 +SELECT t1.*, 5.222 + 5.223 +(SELECT t2.rusname FROM biotopelist AS t2 5.224 +WHERE Left(t2.rangcode, 1) = Left(t1.rangcode, 1) 5.225 +AND Right(t2.rangcode, 8) = '00000000' 5.226 +AND Right(t1.rangcode, 8) <> '00000000') AS class0, 5.227 + 5.228 +(SELECT t2.rusname FROM biotopelist AS t2 5.229 +WHERE Left(t2.rangcode, 3) = Left(t1.rangcode, 3) 5.230 +AND Right(t2.rangcode, 6) = '000000' 5.231 +AND Right(t1.rangcode, 6) <> '000000') AS class1, 5.232 + 5.233 +(SELECT t2.rusname FROM biotopelist AS t2 5.234 +WHERE Left(t2.rangcode, 5) = Left(t1.rangcode, 5) 5.235 +AND Right(t2.rangcode, 4) = '0000' 5.236 +AND Right(t1.rangcode, 4) <> '0000') AS class2, 5.237 + 5.238 +(SELECT t2.rusname FROM biotopelist AS t2 5.239 +WHERE Left(t2.rangcode, 7) = Left(t1.rangcode, 7) 5.240 +AND Right(t2.rangcode, 2) = '00' 5.241 +AND Right(t1.rangcode, 2) <> '00') AS class3 5.242 + 5.243 +FROM biotopelist AS t1 5.244 +WHERE rusname 5.245 +---------------------------------------------------------------------- 5.246 + 5.247 +Шаблон biotope.template содержит инструкцию <%include\photo.template%>, 5.248 +включающую шаблон описания фотографии (файл photo.template): 5.249 + 5.250 +---------------------------------------------------------------------- 5.251 + <фотография num="<%xml_escape get\NUMBER%>" 5.252 + <%optional:автор="<%xml_escape get\authphoto%>" %>text="" 5.253 + file="<%xml_escape image:biotopephotos/<%get\photo%> images/<%get\SUPER.code%>_<%get\NUMBER%>.jpg jpg 300 300%>" 5.254 + big="<%xml_escape copy:biotopephotos/<%get\photo%> images/big/<%get\SUPER.code%>_<%get\NUMBER%>.jpg%>"/> 5.255 +---------------------------------------------------------------------- 5.256 + 5.257 +Соответствующий SQL-запрос для получения описания фотографий 5.258 +(photo.sql): 5.259 + 5.260 +---------------------------------------------------------------------- 5.261 +SELECT * from photos WHERE biotope = ? 5.262 +---------------------------------------------------------------------- 5.263 + 5.264 +Шаблон, генерирующий список классов (файл classes.template): 5.265 + 5.266 +---------------------------------------------------------------------- 5.267 +<?xml version="1.0" encoding="ISO-8859-5"?> 5.268 +<классификация><%query:class_sql [%\ 5.269 + <!-- rangcode: <%xml_escape get\rangcode%> --> 5.270 + <класс id="<%get\NUMBER%>"><%xml_escape get\rusname%></класс>%]%> 5.271 +</классификация> 5.272 +---------------------------------------------------------------------- 5.273 + 5.274 +Соответствующий SQL-запрос (class.sql): 5.275 + 5.276 +---------------------------------------------------------------------- 5.277 +SELECT t1.* 5.278 +FROM biotopelist AS t1 5.279 +WHERE rusname AND Right(t1.rangcode, 8) = '00000000' 5.280 + AND EXISTS 5.281 + (SELECT NULL FROM biotopelist AS t2 5.282 + WHERE Left(t2.rangcode, 1) = Left(t1.rangcode, 1) 5.283 + AND Right(t2.rangcode, 8) <> '00000000') 5.284 +---------------------------------------------------------------------- 5.285 + 5.286 +Шаблон, генерирующий список растений (файл plants.template): 5.287 + 5.288 +---------------------------------------------------------------------- 5.289 +<?xml version="1.0" encoding="ISO-8859-5"?> 5.290 +<растения><%query:plant_sql [%\ 5.291 + <!-- rangcode: <%xml_escape get\rangcode%> --> 5.292 + <растение><%xml_escape get\rusname%></растение>%]%> 5.293 +</растения> 5.294 +---------------------------------------------------------------------- 5.295 + 5.296 +Соответствующий SQL-запрос (plant.sql): 5.297 + 5.298 +---------------------------------------------------------------------- 5.299 +SELECT t1.* 5.300 +FROM biotopelist AS t1 5.301 +WHERE rusname AND Right(t1.rangcode, 2) <> '00' 5.302 +---------------------------------------------------------------------- 5.303 + 5.304 +Система DbReader начинает работу с обработки шаблона index.template, 5.305 +который содержит вызовы перечисленных выше SQL-запросов и включения 5.306 +шаблонов: 5.307 + 5.308 +---------------------------------------------------------------------- 5.309 +<%!: 5.310 + <%prepare:biotope_sql <%read\biotope.sql%>%> 5.311 + <%prepare:photo_sql <%read\photo.sql%>%> 5.312 + <%prepare:class_sql <%read\class.sql%>%> 5.313 + <%prepare:plant_sql <%read\plant.sql%>%> 5.314 + 5.315 + <%query:biotope_sql [%\<%write:<%get\code%>.xml <%include\biotope.template%>%> %]%> 5.316 + 5.317 + <%write:classes.xml <%include\classes.template%>%> 5.318 + <%write:plants.xml <%include\plants.template%>%> 5.319 +%> 5.320 +---------------------------------------------------------------------- 5.321 + 5.322 +Пример сгенерированного XML-файла: 5.323 + 5.324 +---------------------------------------------------------------------- 5.325 +<?xml version="1.0" encoding="ISO-8859-5"?> 5.326 +<!DOCTYPE описание_вида SYSTEM "brief.dtd"> 5.327 +<!-- rangcode: E04020302 --> 5.328 +<описание_вида show="0"> 5.329 + <рисунки display="0"> 5.330 + <фотография num="1" автор="Крышень А.М." text="" 5.331 + file="images/3_1.jpg" 5.332 + big="images/big/3_1.jpg"/> 5.333 + <фотография num="2" автор="Крышень А.М." text="" 5.334 + file="images/3_2.jpg" 5.335 + big="images/big/3_2.jpg"/> 5.336 + </рисунки> 5.337 + <название>Betula sp. - Avenella flexuosa - Polytrichum commune</название> 5.338 + <класс>E. Суходольные местообитания</класс> 5.339 + <подкласс1>Автоморфные влажные</подкласс1> 5.340 + <подкласс2></подкласс2> 5.341 + <подкласс3></подкласс3> 5.342 + <краткая_характеристика rows="3"><![CDATA[Развиваются на луговиковых вырубках лесов черничного типа. Через 5 - 7 лет после рубки порослевая береза выходит из яруса травянистых растений, ее влияние сказывается, в первую очередь, на влажности почвы.]]></краткая_характеристика> 5.343 + <пример_описания rows="3"></пример_описания> 5.344 + <авторы_описания></авторы_описания> 5.345 +</описание_вида> 5.346 +---------------------------------------------------------------------- 5.347 + 5.348 + 5.349 +* Структура программы DbReader 5.350 + 5.351 +Программа DbReader написана на языке программирования Java и состоит 5.352 +из следующих основных классов: 5.353 + 5.354 +ru.karrc.dbreader.DbReader: cодержит точку входа программы. Загружает 5.355 +конфигурацию, устанавливает соединение с источником данных с помощью 5.356 +библиотеки JDBC, запускает обработку основного шаблона. 5.357 + 5.358 +ru.karrc.dbreader.TemplateParser: осуществляет разбор шаблона, 5.359 +обработку инструкций и вызов функций. 5.360 + 5.361 +ru.karrc.dbreader.Function: абстрактный класс. Реализации всех функций 5.362 +DbReader наследуют этот класс. 5.363 + 5.364 +ru.karrc.dbreader.FunctionDataParser: обработчик данных 5.365 +функции. Посволяет получить список аргументов и текст, передаваемый 5.366 +функции. При необходимости вызывает рекурсивную обработку данных с 5.367 +помощью TemplateParser. 5.368 + 5.369 +ru.karrc.dbreader.Functions: содержит реализации функций в виде 5.370 +анонимных классов, наследующих Function. 5.371 + 5.372 +ru.karrc.dbreader.TemplateParser: исключение, выбрасываемое в случае 5.373 +возникновения ошибки при обработке шаблона. 5.374 + 5.375 +Кроме того, реализовано несколько впомогательных классов, которые 5.376 +используются в реализациях функций системы. 5.377 + 5.378 + 5.379 +* Метрики реализованной программной системы. 5.380 + 5.381 +Количество файлов исходного кода: 8, 5.382 +Количество Java-классов (включая анонимные): 27, 5.383 +Общее количество строк исходного текста: 1311, 5.384 +Количество строк кода (исключая пустые строки и комментарии): 812, 5.385 +Количество строк комментариев: 180. 5.386 + 5.387 + 5.388 +* Заключение 5.389 + 5.390 +Автором была разработана программная система DbReader, которая 5.391 +является расширяемым и универсальным средством для представления 5.392 +информации из баз данных в текстовых форматах. С помощью системы 5.393 +DbReader база данных "Местообитания Восточной Фенноскандии" была 5.394 +переведена в XML-формат электронной библиотеки КарНЦ РАН.
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/dist/biotopes/doc/readme.html Thu Dec 14 23:22:05 2006 +0300 6.3 @@ -0,0 +1,86 @@ 6.4 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 6.5 + "DTD/xhtml1-transitional.dtd"> 6.6 + 6.7 +<html> 6.8 + 6.9 +<head> 6.10 + <title>DbReader</title> 6.11 + <meta http-equiv="Content-Type" content="text/html; charset=koi8-r" /> 6.12 +</head> 6.13 + 6.14 +<body> 6.15 +<h1>DbReader</h1> 6.16 + 6.17 +<h2>Установка программы</h2> 6.18 +<ol> 6.19 +<li>Распаковать архив.</li> 6.20 + 6.21 +<li>Установить источник данных:<br /> 6.22 +в Windows 2000: Панель управления/Администрирование/Источники данных (ODBC), добавить biotopes-data.mdb.</li> 6.23 + 6.24 +<li>Настроить программу:<br /> 6.25 +В файле dbreader.properties указать имя, присвоенное источнику данных:<br /> 6.26 + <code>resource: jdbc:odbc:<em>имя</em></code><br /> 6.27 +и путь к каталогу, относительно которого программа будет искать изображения (содержащий biotopephotos и maps):<br /> 6.28 + <code>resource_base: C:\\biotopes</code><br /> 6.29 +(символ '\' необходимо дублировать)</li> 6.30 + 6.31 +<li>Запуск программы:<br /> 6.32 +<code>dbreader.bat</code> или<br /> 6.33 +<code>java -jar dbreader.jar</code>.<br /> 6.34 +Для запуска необходима Java Runtime Environment (JRE) 5.0, можно скачать с <a href="http://java.sun.com/j2se/1.5.0/download.jsp">http://java.sun.com/j2se/1.5.0/download.jsp</a>. Возможно, будет работать и со старыми версиями JRE - не проверял. 6.35 + 6.36 +Все значения файла конфигурации можно переопределять при запуске программы:<br /> 6.37 +команда <code>java -Dru.karrc.dbreader.<em>ключ</em>=<em>значение</em> -jar dbreader.jar</code><br /> 6.38 +(например: <code>java -Dru.karrc.dbreader.log=dbreader.log -jar dbreader.jar</code>)</li> 6.39 +</ol> 6.40 + 6.41 +<h2>Работа программы</h2> 6.42 + 6.43 +<p>Программа выполняет запрос biotope.sql (или другой, указанный в dbreader.properties), после чего обрабатывает файл biotope.template, заменяя найденные в нем инструкции на результаты их выполнения.</p> 6.44 +<p>Формат инструкций: <code><%<em>список_функций</em>[:|\]<em>данные</em>%></code>, <em>список функций</em> - имена функций разделенные пробелом, список может быть пустым. Если указано несколько функций, они выполняются начиная с последней.</p> 6.45 + 6.46 +<h3>Разделители между списком функций и данными</h3> 6.47 + 6.48 +<ul> 6.49 + <li><code>:</code> - данные будут обрабатываться рекурсивно.</li> 6.50 + <li><code>\</code> - данные будут переданы функции без обработки. Можно использовать для экранирования комбинаций символов <code><%</code> и <code>%></code> (<code><%\<%%></code> и <code><%\%%>></code>).</li> 6.51 +</ul> 6.52 + 6.53 +<h3>Функции</h3> 6.54 + 6.55 +<ul> 6.56 + <li><code><%get:<em>имя</em>%></code><br /> 6.57 + Заменяется на значение встроенной переменной или колонки запроса.</li> 6.58 + 6.59 + <li><code><%optional:<em>текст</em>%></code><br /> 6.60 + Заменяется на <em>текст</em>, если в нем найдены инструкции, заменившиеся на непустые строки, иначе заменяется на пустую строку.</li> 6.61 + 6.62 + <li><code><%escape:<em>текст</em>%></code><br /> 6.63 + Заменяет в тексте "опасные" символы (таблица замен задается в файле конфигурации).</li> 6.64 + 6.65 + <li><code><%invoke:<em>имя</em>; <em>парам1</em> <em>парам2</em> ... <em>парамN</em>%></code><br /> 6.66 + Выполняет запрос с параметрами <em>имя</em>.sql и заменяется на результаты обработки шаблона <em>имя</em>.template. Значения параметров подставляются в запрос вместо символа '?'.</li> 6.67 + 6.68 + <li><code><%image:<em>исх_файл</em> <em>кон_файл</em> <em>формат</em> [<em>макс_ширина</em>] [<em>макс_высота</em>]%></code><br /> 6.69 + Загружает изображение из файла <em>исх_файл</em> (путь определяется относительно конфигурационного параметра "resource_base") и преобразует его в указанный формат, сохраняя результат в <em>кон_файл</em>. Если заданы максимальная высота и ширина, большие изображения будут уменьшены. 6.70 +При успешном выполнении, инструкция <code><%image:...%></code> будет заменена на значение <em>кон_файл</em>, иначе - на пустую строку.</li> 6.71 + 6.72 + <li><code><%copy:<em>исх_файл</em> <em>кон_файл</em>%></code><br /> 6.73 + Копирует файл <em>исх_файл</em> (путь определяется относительно конфигурационного параметра "resource_base") в <em>кон_файл</em>. При успешном выполнении, инструкция <code><%copy:...%></code> будет заменена на значение <em>кон_файл</em>, иначе - на пустую строку.</li> 6.74 +</ul> 6.75 + 6.76 +<h3>Встроенные переменные</h3> 6.77 + 6.78 +<p><code>NUMBER</code> - порядковый номер строки результата выполнения запроса. 6.79 +Чтобы обратиться к переменной запроса, из которого обрабатываемый шаблон был вызван с помощью функции invoke, перед именем переменной нужно добавить <code>SUPER.</code> (например: <code>SUPER.NUMBER</code>).</p> 6.80 + 6.81 +<h3>Пример</h3> 6.82 + 6.83 +<p>Следующая инструкция получит значение из столбца name и заменит в нем специальные символы:</p> 6.84 +<p><code><%escape get:name%></code></p> 6.85 + 6.86 +<p align="right"><i><a href="mailto:kryshen@cs.karelia.ru">Михаил Крышень</a></i></p> 6.87 + 6.88 +</body> 6.89 +</html>
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/dist/biotopes/doc/readme.txt Thu Dec 14 23:22:05 2006 +0300 7.3 @@ -0,0 +1,63 @@ 7.4 +text/plain; charset=UTF-8 7.5 + 7.6 +пёя│я┌п╟п╫п╬п╡п╨п╟ п©я─п╬пЁя─п╟п╪п╪я▀ 7.7 +------------------- 7.8 + 7.9 +1. п═п╟я│п©п╟п╨п╬п╡п╟я┌я▄ п╟я─я┘п╦п╡. 7.10 + 7.11 +2. пёя│я┌п╟п╫п╬п╡п╦я┌я▄ п╦я│я┌п╬я┤п╫п╦п╨ п╢п╟п╫п╫я▀я┘: 7.12 +п╡ Windows 2000: п÷п╟п╫п╣п╩я▄ я┐п©я─п╟п╡п╩п╣п╫п╦я▐/п░п╢п╪п╦п╫п╦я│я┌я─п╦я─п╬п╡п╟п╫п╦п╣/п≤я│я┌п╬я┤п╫п╦п╨п╦ п╢п╟п╫п╫я▀я┘ (ODBC), п╢п╬п╠п╟п╡п╦я┌я▄ biotopes.mdb. 7.13 + 7.14 +3. п²п╟я│я┌я─п╬п╦я┌я▄ п©я─п╬пЁя─п╟п╪п╪я┐: 7.15 +п▓ я└п╟п╧п╩п╣ dbreader.properties я┐п╨п╟п╥п╟я┌я▄ п╦п╪я▐, п©я─п╦я│п╡п╬п╣п╫п╫п╬п╣ п╦я│я┌п╬я┤п╫п╦п╨я┐ п╢п╟п╫п╫я▀я┘: 7.16 + "resource: jdbc:odbc:<п╦п╪я▐>" 7.17 +п╦ п©я┐я┌я▄ п╨ п╨п╟я┌п╟п╩п╬пЁя┐, п╬я┌п╫п╬я│п╦я┌п╣п╩я▄п╫п╬ п╨п╬я┌п╬я─п╬пЁп╬ п©я─п╬пЁя─п╟п╪п╪п╟ п╠я┐п╢п╣я┌ п╦я│п╨п╟я┌я▄ п╦п╥п╬п╠я─п╟п╤п╣п╫п╦я▐ (я│п╬п╢п╣я─п╤п╟я┴п╦п╧ biotopephotos п╦ maps): 7.18 + "resource_base: C:\\biotopes" 7.19 +(я│п╦п╪п╡п╬п╩ '\' п╫п╣п╬п╠я┘п╬п╢п╦п╪п╬ п╢я┐п╠п╩п╦я─п╬п╡п╟я┌я▄) 7.20 + 7.21 +4. п≈п╟п©я┐я│п╨ п©я─п╬пЁя─п╟п╪п╪я▀: dbreader.bat п╦п╩п╦ "java -jar dbreader.jar" 7.22 +п■п╩я▐ п╥п╟п©я┐я│п╨п╟ п╫п╣п╬п╠я┘п╬п╢п╦п╪п╟ Java Runtime Environment (JRE) 5.0, п╪п╬п╤п╫п╬ я│п╨п╟я┤п╟я┌я▄ я│ http://java.sun.com/j2se/1.5.0/download.jsp. п▓п╬п╥п╪п╬п╤п╫п╬, п╠я┐п╢п╣я┌ я─п╟п╠п╬я┌п╟я┌я▄ п╦ я│п╬ я│я┌п╟я─я▀п╪п╦ п╡п╣я─я│п╦я▐п╪п╦ JRE - п╫п╣ п©я─п╬п╡п╣я─я▐п╩. 7.23 + 7.24 +п▓я│п╣ п╥п╫п╟я┤п╣п╫п╦я▐ я└п╟п╧п╩п╟ п╨п╬п╫я└п╦пЁя┐я─п╟я├п╦п╦ п╪п╬п╤п╫п╬ п©п╣я─п╣п╬п©я─п╣п╢п╣п╩я▐я┌я▄ п©я─п╦ п╥п╟п©я┐я│п╨п╣ п©я─п╬пЁя─п╟п╪п╪я▀: 7.25 + п╨п╬п╪п╟п╫п╢п╟ "java -Dru.karrc.dbreader.<п╨п╩я▌я┤>=<п╥п╫п╟я┤п╣п╫п╦п╣> -jar dbreader.jar" 7.26 +(п╫п╟п©я─п╦п╪п╣я─: "java -Dru.karrc.dbreader.log=dbreader.log -jar dbreader.jar") 7.27 + 7.28 + 7.29 +п═п╟п╠п╬я┌п╟ п©я─п╬пЁя─п╟п╪п╪я▀ 7.30 +---------------- 7.31 + 7.32 +п÷я─п╬пЁя─п╟п╪п╪п╟ п╡я▀п©п╬п╩п╫я▐п╣я┌ п╥п╟п©я─п╬я│ biotope.sql (п╦п╩п╦ п╢я─я┐пЁп╬п╧, я┐п╨п╟п╥п╟п╫п╫я▀п╧ п╡ dbreader.properties), п©п╬я│п╩п╣ я┤п╣пЁп╬ п╬п╠я─п╟п╠п╟я┌я▀п╡п╟п╣я┌ я└п╟п╧п╩ biotope.template, п╥п╟п╪п╣п╫я▐я▐ п╫п╟п╧п╢п╣п╫п╫я▀п╣ п╡ п╫п╣п╪ п╦п╫я│я┌я─я┐п╨я├п╦п╦ п╫п╟ я─п╣п╥я┐п╩я▄я┌п╟я┌я▀ п╦я┘ п╡я▀п©п╬п╩п╫п╣п╫п╦я▐. 7.33 + 7.34 +п╓п╬я─п╪п╟я┌ п╦п╫я│я┌я─я┐п╨я├п╦п╧: "<%я│п©п╦я│п╬п╨_я└я┐п╫п╨я├п╦п╧[:|\]п╢п╟п╫п╫я▀п╣%>", я│п©п╦я│п╬п╨ я└я┐п╫п╨я├п╦п╧ - п╦п╪п╣п╫п╟ я└я┐п╫п╨я├п╦п╧ я─п╟п╥п╢п╣п╩п╣п╫п╫я▀п╣ п©я─п╬п╠п╣п╩п╬п╪, я│п©п╦я│п╬п╨ п╪п╬п╤п╣я┌ п╠я▀я┌я▄ п©я┐я│я┌я▀п╪. п∙я│п╩п╦ я┐п╨п╟п╥п╟п╫п╬ п╫п╣я│п╨п╬п╩я▄п╨п╬ я└я┐п╫п╨я├п╦п╧, п╬п╫п╦ п╡я▀п©п╬п╩п╫я▐я▌я┌я│я▐ п╫п╟я┤п╦п╫п╟я▐ я│ п©п╬я│п╩п╣п╢п╫п╣п╧. 7.35 + 7.36 +п═п╟п╥п╢п╣п╩п╦я┌п╣п╩п╦ п╪п╣п╤п╢я┐ я│п©п╦я│п╨п╬п╪ я└я┐п╫п╨я├п╦п╧ п╦ п╢п╟п╫п╫я▀п╪п╦: 7.37 +':' - п╢п╟п╫п╫я▀п╣ п╠я┐п╢я┐я┌ п╬п╠я─п╟п╠п╟я┌я▀п╡п╟я┌я▄я│я▐ я─п╣п╨я┐я─я│п╦п╡п╫п╬. 7.38 +'\' - п╢п╟п╫п╫я▀п╣ п╠я┐п╢я┐я┌ п©п╣я─п╣п╢п╟п╫я▀ я└я┐п╫п╨я├п╦п╦ п╠п╣п╥ п╬п╠я─п╟п╠п╬я┌п╨п╦. п°п╬п╤п╫п╬ п╦я│п©п╬п╩я▄п╥п╬п╡п╟я┌я▄ п╢п╩я▐ я█п╨я─п╟п╫п╦я─п╬п╡п╟п╫п╦я▐ п╨п╬п╪п╠п╦п╫п╟я├п╦п╧ я│п╦п╪п╡п╬п╩п╬п╡ "<%" п╦ "%>" ("<%\<%%>" п╦ "<%\%%>>"). 7.39 + 7.40 +п╓я┐п╫п╨я├п╦п╦: 7.41 +<%get:<п╦п╪я▐>%> - п╥п╟п╪п╣п╫я▐п╣я┌я│я▐ п╫п╟ п╥п╫п╟я┤п╣п╫п╦п╣ п╡я│я┌я─п╬п╣п╫п╫п╬п╧ п©п╣я─п╣п╪п╣п╫п╫п╬п╧ п╦п╩п╦ п╨п╬п╩п╬п╫п╨п╦ п╥п╟п©я─п╬я│п╟. 7.42 + 7.43 +<%optional:<я┌п╣п╨я│я┌>%> 7.44 +п≈п╟п╪п╣п╫я▐п╣я┌я│я▐ п╫п╟ <я┌п╣п╨я│я┌>, п╣я│п╩п╦ п╡ п╫п╣п╪ п╫п╟п╧п╢п╣п╫я▀ п╦п╫я│я┌я─я┐п╨я├п╦п╦, п╥п╟п╪п╣п╫п╦п╡я┬п╦п╣я│я▐ п╫п╟ п╫п╣п©я┐я│я┌я▀п╣ я│я┌я─п╬п╨п╦, п╦п╫п╟я┤п╣ п╥п╟п╪п╣п╫я▐п╣я┌я│я▐ п╫п╟ п©я┐я│я┌я┐я▌ я│я┌я─п╬п╨я┐. 7.45 + 7.46 +<%escape:<я┌п╣п╨я│я┌>%> 7.47 +п≈п╟п╪п╣п╫я▐п╣я┌ п╡ я┌п╣п╨я│я┌п╣ "п╬п©п╟я│п╫я▀п╣" я│п╦п╪п╡п╬п╩я▀ (я┌п╟п╠п╩п╦я├п╟ п╥п╟п╪п╣п╫ п╥п╟п╢п╟п╣я┌я│я▐ п╡ я└п╟п╧п╩п╣ п╨п╬п╫я└п╦пЁя┐я─п╟я├п╦п╦). 7.48 + 7.49 +<%invoke:<п╦п╪я▐> <п©п╟я─п╟п╪1> <п©п╟я─п╟п╪2> ... <п©п╟я─п╟п╪N>%> 7.50 +п▓я▀п©п╬п╩п╫я▐п╣я┌ п╥п╟п©я─п╬я│ я│ п©п╟я─п╟п╪п╣я┌я─п╟п╪п╦ <п╦п╪я▐>.sql п╦ п╥п╟п╪п╣п╫я▐п╣я┌я│я▐ п╫п╟ я─п╣п╥я┐п╩я▄я┌п╟я┌я▀ п╬п╠я─п╟п╠п╬я┌п╨п╦ я┬п╟п╠п╩п╬п╫п╟ <п╦п╪я▐>.template. п≈п╫п╟я┤п╣п╫п╦я▐ п©п╟я─п╟п╪п╣я┌я─п╬п╡ п©п╬п╢я│я┌п╟п╡п╩я▐я▌я┌я│я▐ п╡ п╥п╟п©я─п╬я│ п╡п╪п╣я│я┌п╬ я│п╦п╪п╡п╬п╩п╟ '?'. 7.51 + 7.52 +<%image:<п╦я│я┘_я└п╟п╧п╩> <п╨п╬п╫_я└п╟п╧п╩> <я└п╬я─п╪п╟я┌> [<п╪п╟п╨я│_я┬п╦я─п╦п╫п╟>] [<п╪п╟п╨я│_п╡я▀я│п╬я┌п╟>]%> 7.53 +п≈п╟пЁя─я┐п╤п╟п╣я┌ п╦п╥п╬п╠я─п╟п╤п╣п╫п╦п╣ п╦п╥ я└п╟п╧п╩п╟ <п╦я│я┘_я└п╟п╧п╩> (п©я┐я┌я▄ п╬п©я─п╣п╢п╣п╩я▐п╣я┌я│я▐ п╬я┌п╫п╬я│п╦я┌п╣п╩я▄п╫п╬ п╨п╬п╫я└п╦пЁя┐я─п╟я├п╦п╬п╫п╫п╬пЁп╬ п©п╟я─п╟п╪п╣я┌я─п╟ "resource_base") п╦ п©я─п╣п╬п╠я─п╟п╥я┐п╣я┌ п╣пЁп╬ п╡ я┐п╨п╟п╥п╟п╫п╫я▀п╧ я└п╬я─п╪п╟я┌, я│п╬я┘я─п╟п╫я▐я▐ я─п╣п╥я┐п╩я▄я┌п╟я┌ п╡ <п╨п╬п╫_я└п╟п╧п╩>. п∙я│п╩п╦ п╥п╟п╢п╟п╫я▀ п╪п╟п╨я│п╦п╪п╟п╩я▄п╫п╟я▐ п╡я▀я│п╬я┌п╟ п╦ я┬п╦я─п╦п╫п╟, п╠п╬п╩я▄я┬п╦п╣ п╦п╥п╬п╠я─п╟п╤п╣п╫п╦я▐ п╠я┐п╢я┐я┌ я┐п╪п╣п╫я▄я┬п╣п╫я▀. 7.54 +п÷я─п╦ я┐я│п©п╣я┬п╫п╬п╪ п╡я▀п©п╬п╩п╫п╣п╫п╦п╦, п╦п╫я│я┌я─я┐п╨я├п╦я▐ "<%!image ...%>" п╠я┐п╢п╣я┌ п╥п╟п╪п╣п╫п╣п╫п╟ п╫п╟ п╥п╫п╟я┤п╣п╫п╦п╣ <п╨п╬п╫_я└п╟п╧п╩>, п╦п╫п╟я┤п╣ - п╫п╟ п©я┐я│я┌я┐я▌ я│я┌я─п╬п╨я┐. 7.55 + 7.56 +<%copy:<п╦я│я┘_я└п╟п╧п╩> <п╨п╬п╫_я└п╟п╧п╩>%> 7.57 +п п╬п©п╦я─я┐п╣я┌ я└п╟п╧п╩ <п╦я│я┘_я└п╟п╧п╩> (п©я┐я┌я▄ п╬п©я─п╣п╢п╣п╩я▐п╣я┌я│я▐ п╬я┌п╫п╬я│п╦я┌п╣п╩я▄п╫п╬ п╨п╬п╫я└п╦пЁя┐я─п╟я├п╦п╬п╫п╫п╬пЁп╬ п©п╟я─п╟п╪п╣я┌я─п╟ "resource_base"). 7.58 +п÷я─п╦ я┐я│п©п╣я┬п╫п╬п╪ п╡я▀п©п╬п╩п╫п╣п╫п╦п╦, п╦п╫я│я┌я─я┐п╨я├п╦я▐ "<%!copy ...%>" п╠я┐п╢п╣я┌ п╥п╟п╪п╣п╫п╣п╫п╟ п╫п╟ п╥п╫п╟я┤п╣п╫п╦п╣ <п╨п╬п╫_я└п╟п╧п╩>, п╦п╫п╟я┤п╣ - п╫п╟ п©я┐я│я┌я┐я▌ я│я┌я─п╬п╨я┐. 7.59 + 7.60 +п▓я│я┌я─п╬п╣п╫п╫я▀п╣ п©п╣я─п╣п╪п╣п╫п╫я▀п╣: 7.61 +NUMBER - п©п╬я─я▐п╢п╨п╬п╡я▀п╧ п╫п╬п╪п╣я─ я│я┌я─п╬п╨п╦ я─п╣п╥я┐п╩я▄я┌п╟я┌п╟ п╡я▀п©п╬п╩п╫п╣п╫п╦я▐ п╥п╟п©я─п╬я│п╟. 7.62 +п╖я┌п╬п╠я▀ п╬п╠я─п╟я┌п╦я┌я▄я│я▐ п╨ п©п╣я─п╣п╪п╣п╫п╫п╬п╧ п╥п╟п©я─п╬я│п╟, п╦п╥ п╨п╬я┌п╬я─п╬пЁп╬ п╬п╠я─п╟п╠п╟я┌я▀п╡п╟п╣п╪я▀п╧ я┬п╟п╠п╩п╬п╫ п╠я▀п╩ п╡я▀п╥п╡п╟п╫ я│ п©п╬п╪п╬я┴я▄я▌ я└я┐п╫п╨я├п╦п╦ invoke, п©п╣я─п╣п╢ п╦п╪п╣п╫п╣п╪ п©п╣я─п╣п╪п╣п╫п╫п╬п╧ п╫я┐п╤п╫п╬ п╢п╬п╠п╟п╡п╦я┌я▄ "SUPER." (п╫п╟п©я─п╦п╪п╣я─: "SUPER.NUMBER"). 7.63 + 7.64 +п÷я─п╦п╪п╣я─: 7.65 +п║п╩п╣п╢я┐я▌я┴п╟я▐ п╦п╫я│я┌я─я┐п╨я├п╦я▐ п©п╬п╩я┐я┤п╦я┌ п╥п╫п╟я┤п╣п╫п╦п╣ п╦п╥ я│я┌п╬п╩п╠я├п╟ name п╦ п╥п╟п╪п╣п╫п╦я┌ п╡ п╫п╣п╪ я│п©п╣я├п╦п╟п╩я▄п╫я▀п╣ я│п╦п╪п╡п╬п╩я▀: 7.66 +<%escape get:name%>
8.1 --- a/dist/biotopes/main.template Tue May 16 18:04:09 2006 +0400 8.2 +++ b/dist/biotopes/main.template Thu Dec 14 23:22:05 2006 +0300 8.3 @@ -4,7 +4,7 @@ 8.4 <%prepare:class_sql <%read\class.sql%>%> 8.5 <%prepare:plant_sql <%read\plant.sql%>%> 8.6 8.7 - <%query:biotope_sql [%\<%write:<%get\code%>.xml <%include\biotope.template%>%> %]%> 8.8 + <%query:biotope_sql [%\<%write:<%db\code%>.xml <%include\biotope.template%>%> %]%> 8.9 8.10 <%write:classes.xml <%include\classes.template%>%> 8.11 <%write:plants.xml <%include\plants.template%>%>
9.1 --- a/dist/biotopes/photo.template Tue May 16 18:04:09 2006 +0400 9.2 +++ b/dist/biotopes/photo.template Thu Dec 14 23:22:05 2006 +0300 9.3 @@ -1,3 +1,3 @@ 9.4 - <ДчБчсЮпДьО num="<%xml_escape get\NUMBER%>" <%optional:прБчЮ="<%xml_escape get\authphoto%>" %>text="" 9.5 - file="<%xml_escape image:biotopephotos/<%get\photo%> images/<%get\SUPER.code%>_<%get\NUMBER%>.jpg jpg 300 300%>" 9.6 - big="<%xml_escape copy:biotopephotos/<%get\photo%> images/big/<%get\SUPER.code%>_<%get\NUMBER%>.jpg%>"/> 9.7 + <ДчБчсЮпДьО num="<%number\%>" <%optional:прБчЮ="<%xml_escape db\authphoto%>" %>text="" 9.8 + file="<%xml_escape image:biotopephotos/<%db\photo%> images/<%super.db\code%>_<%number\%>.jpg jpg 300 300%>" 9.9 + big="<%xml_escape copy:biotopephotos/<%db\photo%> images/big/<%super.db\code%>_<%number\%>.jpg%>"/>
10.1 --- a/dist/biotopes/plants.template Tue May 16 18:04:09 2006 +0400 10.2 +++ b/dist/biotopes/plants.template Thu Dec 14 23:22:05 2006 +0300 10.3 @@ -1,5 +1,5 @@ 10.4 <?xml version="1.0" encoding="ISO-8859-5"?> 10.5 <ЮпАБущьО><%query:plant_sql [%\ 10.6 - <!-- rangcode: <%xml_escape get\rangcode%> --> 10.7 - <ЮпАБущьу><%xml_escape get\rusname%></ЮпАБущьу>%]%> 10.8 + <!-- rangcode: <%xml_escape db\rangcode%> --> 10.9 + <ЮпАБущьу><%xml_escape db\rusname%></ЮпАБущьу>%]%> 10.10 </ЮпАБущьО>
11.1 --- a/dist/readme.html Tue May 16 18:04:09 2006 +0400 11.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 11.3 @@ -1,86 +0,0 @@ 11.4 -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 11.5 - "DTD/xhtml1-transitional.dtd"> 11.6 - 11.7 -<html> 11.8 - 11.9 -<head> 11.10 - <title>DbReader</title> 11.11 - <meta http-equiv="Content-Type" content="text/html; charset=koi8-r" /> 11.12 -</head> 11.13 - 11.14 -<body> 11.15 -<h1>DbReader</h1> 11.16 - 11.17 -<h2>Установка программы</h2> 11.18 -<ol> 11.19 -<li>Распаковать архив.</li> 11.20 - 11.21 -<li>Установить источник данных:<br /> 11.22 -в Windows 2000: Панель управления/Администрирование/Источники данных (ODBC), добавить biotopes-data.mdb.</li> 11.23 - 11.24 -<li>Настроить программу:<br /> 11.25 -В файле dbreader.properties указать имя, присвоенное источнику данных:<br /> 11.26 - <code>resource: jdbc:odbc:<em>имя</em></code><br /> 11.27 -и путь к каталогу, относительно которого программа будет искать изображения (содержащий biotopephotos и maps):<br /> 11.28 - <code>resource_base: C:\\biotopes</code><br /> 11.29 -(символ '\' необходимо дублировать)</li> 11.30 - 11.31 -<li>Запуск программы:<br /> 11.32 -<code>dbreader.bat</code> или<br /> 11.33 -<code>java -jar dbreader.jar</code>.<br /> 11.34 -Для запуска необходима Java Runtime Environment (JRE) 5.0, можно скачать с <a href="http://java.sun.com/j2se/1.5.0/download.jsp">http://java.sun.com/j2se/1.5.0/download.jsp</a>. Возможно, будет работать и со старыми версиями JRE - не проверял. 11.35 - 11.36 -Все значения файла конфигурации можно переопределять при запуске программы:<br /> 11.37 -команда <code>java -Dru.karrc.dbreader.<em>ключ</em>=<em>значение</em> -jar dbreader.jar</code><br /> 11.38 -(например: <code>java -Dru.karrc.dbreader.log=dbreader.log -jar dbreader.jar</code>)</li> 11.39 -</ol> 11.40 - 11.41 -<h2>Работа программы</h2> 11.42 - 11.43 -<p>Программа выполняет запрос biotope.sql (или другой, указанный в dbreader.properties), после чего обрабатывает файл biotope.template, заменяя найденные в нем инструкции на результаты их выполнения.</p> 11.44 -<p>Формат инструкций: <code><%<em>список_функций</em>[:|\]<em>данные</em>%></code>, <em>список функций</em> - имена функций разделенные пробелом, список может быть пустым. Если указано несколько функций, они выполняются начиная с последней.</p> 11.45 - 11.46 -<h3>Разделители между списком функций и данными</h3> 11.47 - 11.48 -<ul> 11.49 - <li><code>:</code> - данные будут обрабатываться рекурсивно.</li> 11.50 - <li><code>\</code> - данные будут переданы функции без обработки. Можно использовать для экранирования комбинаций символов <code><%</code> и <code>%></code> (<code><%\<%%></code> и <code><%\%%>></code>).</li> 11.51 -</ul> 11.52 - 11.53 -<h3>Функции</h3> 11.54 - 11.55 -<ul> 11.56 - <li><code><%get:<em>имя</em>%></code><br /> 11.57 - Заменяется на значение встроенной переменной или колонки запроса.</li> 11.58 - 11.59 - <li><code><%optional:<em>текст</em>%></code><br /> 11.60 - Заменяется на <em>текст</em>, если в нем найдены инструкции, заменившиеся на непустые строки, иначе заменяется на пустую строку.</li> 11.61 - 11.62 - <li><code><%escape:<em>текст</em>%></code><br /> 11.63 - Заменяет в тексте "опасные" символы (таблица замен задается в файле конфигурации).</li> 11.64 - 11.65 - <li><code><%invoke:<em>имя</em>; <em>парам1</em> <em>парам2</em> ... <em>парамN</em>%></code><br /> 11.66 - Выполняет запрос с параметрами <em>имя</em>.sql и заменяется на результаты обработки шаблона <em>имя</em>.template. Значения параметров подставляются в запрос вместо символа '?'.</li> 11.67 - 11.68 - <li><code><%image:<em>исх_файл</em> <em>кон_файл</em> <em>формат</em> [<em>макс_ширина</em>] [<em>макс_высота</em>]%></code><br /> 11.69 - Загружает изображение из файла <em>исх_файл</em> (путь определяется относительно конфигурационного параметра "resource_base") и преобразует его в указанный формат, сохраняя результат в <em>кон_файл</em>. Если заданы максимальная высота и ширина, большие изображения будут уменьшены. 11.70 -При успешном выполнении, инструкция <code><%image:...%></code> будет заменена на значение <em>кон_файл</em>, иначе - на пустую строку.</li> 11.71 - 11.72 - <li><code><%copy:<em>исх_файл</em> <em>кон_файл</em>%></code><br /> 11.73 - Копирует файл <em>исх_файл</em> (путь определяется относительно конфигурационного параметра "resource_base") в <em>кон_файл</em>. При успешном выполнении, инструкция <code><%copy:...%></code> будет заменена на значение <em>кон_файл</em>, иначе - на пустую строку.</li> 11.74 -</ul> 11.75 - 11.76 -<h3>Встроенные переменные</h3> 11.77 - 11.78 -<p><code>NUMBER</code> - порядковый номер строки результата выполнения запроса. 11.79 -Чтобы обратиться к переменной запроса, из которого обрабатываемый шаблон был вызван с помощью функции invoke, перед именем переменной нужно добавить <code>SUPER.</code> (например: <code>SUPER.NUMBER</code>).</p> 11.80 - 11.81 -<h3>Пример</h3> 11.82 - 11.83 -<p>Следующая инструкция получит значение из столбца name и заменит в нем специальные символы:</p> 11.84 -<p><code><%escape get:name%></code></p> 11.85 - 11.86 -<p align="right"><i><a href="mailto:kryshen@cs.karelia.ru">Михаил Крышень</a></i></p> 11.87 - 11.88 -</body> 11.89 -</html>
12.1 --- a/dist/readme.txt Tue May 16 18:04:09 2006 +0400 12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 12.3 @@ -1,63 +0,0 @@ 12.4 -text/plain; charset=UTF-8 12.5 - 12.6 -пёя│я┌п╟п╫п╬п╡п╨п╟ п©я─п╬пЁя─п╟п╪п╪я▀ 12.7 -------------------- 12.8 - 12.9 -1. п═п╟я│п©п╟п╨п╬п╡п╟я┌я▄ п╟я─я┘п╦п╡. 12.10 - 12.11 -2. пёя│я┌п╟п╫п╬п╡п╦я┌я▄ п╦я│я┌п╬я┤п╫п╦п╨ п╢п╟п╫п╫я▀я┘: 12.12 -п╡ Windows 2000: п÷п╟п╫п╣п╩я▄ я┐п©я─п╟п╡п╩п╣п╫п╦я▐/п░п╢п╪п╦п╫п╦я│я┌я─п╦я─п╬п╡п╟п╫п╦п╣/п≤я│я┌п╬я┤п╫п╦п╨п╦ п╢п╟п╫п╫я▀я┘ (ODBC), п╢п╬п╠п╟п╡п╦я┌я▄ biotopes.mdb. 12.13 - 12.14 -3. п²п╟я│я┌я─п╬п╦я┌я▄ п©я─п╬пЁя─п╟п╪п╪я┐: 12.15 -п▓ я└п╟п╧п╩п╣ dbreader.properties я┐п╨п╟п╥п╟я┌я▄ п╦п╪я▐, п©я─п╦я│п╡п╬п╣п╫п╫п╬п╣ п╦я│я┌п╬я┤п╫п╦п╨я┐ п╢п╟п╫п╫я▀я┘: 12.16 - "resource: jdbc:odbc:<п╦п╪я▐>" 12.17 -п╦ п©я┐я┌я▄ п╨ п╨п╟я┌п╟п╩п╬пЁя┐, п╬я┌п╫п╬я│п╦я┌п╣п╩я▄п╫п╬ п╨п╬я┌п╬я─п╬пЁп╬ п©я─п╬пЁя─п╟п╪п╪п╟ п╠я┐п╢п╣я┌ п╦я│п╨п╟я┌я▄ п╦п╥п╬п╠я─п╟п╤п╣п╫п╦я▐ (я│п╬п╢п╣я─п╤п╟я┴п╦п╧ biotopephotos п╦ maps): 12.18 - "resource_base: C:\\biotopes" 12.19 -(я│п╦п╪п╡п╬п╩ '\' п╫п╣п╬п╠я┘п╬п╢п╦п╪п╬ п╢я┐п╠п╩п╦я─п╬п╡п╟я┌я▄) 12.20 - 12.21 -4. п≈п╟п©я┐я│п╨ п©я─п╬пЁя─п╟п╪п╪я▀: dbreader.bat п╦п╩п╦ "java -jar dbreader.jar" 12.22 -п■п╩я▐ п╥п╟п©я┐я│п╨п╟ п╫п╣п╬п╠я┘п╬п╢п╦п╪п╟ Java Runtime Environment (JRE) 5.0, п╪п╬п╤п╫п╬ я│п╨п╟я┤п╟я┌я▄ я│ http://java.sun.com/j2se/1.5.0/download.jsp. п▓п╬п╥п╪п╬п╤п╫п╬, п╠я┐п╢п╣я┌ я─п╟п╠п╬я┌п╟я┌я▄ п╦ я│п╬ я│я┌п╟я─я▀п╪п╦ п╡п╣я─я│п╦я▐п╪п╦ JRE - п╫п╣ п©я─п╬п╡п╣я─я▐п╩. 12.23 - 12.24 -п▓я│п╣ п╥п╫п╟я┤п╣п╫п╦я▐ я└п╟п╧п╩п╟ п╨п╬п╫я└п╦пЁя┐я─п╟я├п╦п╦ п╪п╬п╤п╫п╬ п©п╣я─п╣п╬п©я─п╣п╢п╣п╩я▐я┌я▄ п©я─п╦ п╥п╟п©я┐я│п╨п╣ п©я─п╬пЁя─п╟п╪п╪я▀: 12.25 - п╨п╬п╪п╟п╫п╢п╟ "java -Dru.karrc.dbreader.<п╨п╩я▌я┤>=<п╥п╫п╟я┤п╣п╫п╦п╣> -jar dbreader.jar" 12.26 -(п╫п╟п©я─п╦п╪п╣я─: "java -Dru.karrc.dbreader.log=dbreader.log -jar dbreader.jar") 12.27 - 12.28 - 12.29 -п═п╟п╠п╬я┌п╟ п©я─п╬пЁя─п╟п╪п╪я▀ 12.30 ----------------- 12.31 - 12.32 -п÷я─п╬пЁя─п╟п╪п╪п╟ п╡я▀п©п╬п╩п╫я▐п╣я┌ п╥п╟п©я─п╬я│ biotope.sql (п╦п╩п╦ п╢я─я┐пЁп╬п╧, я┐п╨п╟п╥п╟п╫п╫я▀п╧ п╡ dbreader.properties), п©п╬я│п╩п╣ я┤п╣пЁп╬ п╬п╠я─п╟п╠п╟я┌я▀п╡п╟п╣я┌ я└п╟п╧п╩ biotope.template, п╥п╟п╪п╣п╫я▐я▐ п╫п╟п╧п╢п╣п╫п╫я▀п╣ п╡ п╫п╣п╪ п╦п╫я│я┌я─я┐п╨я├п╦п╦ п╫п╟ я─п╣п╥я┐п╩я▄я┌п╟я┌я▀ п╦я┘ п╡я▀п©п╬п╩п╫п╣п╫п╦я▐. 12.33 - 12.34 -п╓п╬я─п╪п╟я┌ п╦п╫я│я┌я─я┐п╨я├п╦п╧: "<%я│п©п╦я│п╬п╨_я└я┐п╫п╨я├п╦п╧[:|\]п╢п╟п╫п╫я▀п╣%>", я│п©п╦я│п╬п╨ я└я┐п╫п╨я├п╦п╧ - п╦п╪п╣п╫п╟ я└я┐п╫п╨я├п╦п╧ я─п╟п╥п╢п╣п╩п╣п╫п╫я▀п╣ п©я─п╬п╠п╣п╩п╬п╪, я│п©п╦я│п╬п╨ п╪п╬п╤п╣я┌ п╠я▀я┌я▄ п©я┐я│я┌я▀п╪. п∙я│п╩п╦ я┐п╨п╟п╥п╟п╫п╬ п╫п╣я│п╨п╬п╩я▄п╨п╬ я└я┐п╫п╨я├п╦п╧, п╬п╫п╦ п╡я▀п©п╬п╩п╫я▐я▌я┌я│я▐ п╫п╟я┤п╦п╫п╟я▐ я│ п©п╬я│п╩п╣п╢п╫п╣п╧. 12.35 - 12.36 -п═п╟п╥п╢п╣п╩п╦я┌п╣п╩п╦ п╪п╣п╤п╢я┐ я│п©п╦я│п╨п╬п╪ я└я┐п╫п╨я├п╦п╧ п╦ п╢п╟п╫п╫я▀п╪п╦: 12.37 -':' - п╢п╟п╫п╫я▀п╣ п╠я┐п╢я┐я┌ п╬п╠я─п╟п╠п╟я┌я▀п╡п╟я┌я▄я│я▐ я─п╣п╨я┐я─я│п╦п╡п╫п╬. 12.38 -'\' - п╢п╟п╫п╫я▀п╣ п╠я┐п╢я┐я┌ п©п╣я─п╣п╢п╟п╫я▀ я└я┐п╫п╨я├п╦п╦ п╠п╣п╥ п╬п╠я─п╟п╠п╬я┌п╨п╦. п°п╬п╤п╫п╬ п╦я│п©п╬п╩я▄п╥п╬п╡п╟я┌я▄ п╢п╩я▐ я█п╨я─п╟п╫п╦я─п╬п╡п╟п╫п╦я▐ п╨п╬п╪п╠п╦п╫п╟я├п╦п╧ я│п╦п╪п╡п╬п╩п╬п╡ "<%" п╦ "%>" ("<%\<%%>" п╦ "<%\%%>>"). 12.39 - 12.40 -п╓я┐п╫п╨я├п╦п╦: 12.41 -<%get:<п╦п╪я▐>%> - п╥п╟п╪п╣п╫я▐п╣я┌я│я▐ п╫п╟ п╥п╫п╟я┤п╣п╫п╦п╣ п╡я│я┌я─п╬п╣п╫п╫п╬п╧ п©п╣я─п╣п╪п╣п╫п╫п╬п╧ п╦п╩п╦ п╨п╬п╩п╬п╫п╨п╦ п╥п╟п©я─п╬я│п╟. 12.42 - 12.43 -<%optional:<я┌п╣п╨я│я┌>%> 12.44 -п≈п╟п╪п╣п╫я▐п╣я┌я│я▐ п╫п╟ <я┌п╣п╨я│я┌>, п╣я│п╩п╦ п╡ п╫п╣п╪ п╫п╟п╧п╢п╣п╫я▀ п╦п╫я│я┌я─я┐п╨я├п╦п╦, п╥п╟п╪п╣п╫п╦п╡я┬п╦п╣я│я▐ п╫п╟ п╫п╣п©я┐я│я┌я▀п╣ я│я┌я─п╬п╨п╦, п╦п╫п╟я┤п╣ п╥п╟п╪п╣п╫я▐п╣я┌я│я▐ п╫п╟ п©я┐я│я┌я┐я▌ я│я┌я─п╬п╨я┐. 12.45 - 12.46 -<%escape:<я┌п╣п╨я│я┌>%> 12.47 -п≈п╟п╪п╣п╫я▐п╣я┌ п╡ я┌п╣п╨я│я┌п╣ "п╬п©п╟я│п╫я▀п╣" я│п╦п╪п╡п╬п╩я▀ (я┌п╟п╠п╩п╦я├п╟ п╥п╟п╪п╣п╫ п╥п╟п╢п╟п╣я┌я│я▐ п╡ я└п╟п╧п╩п╣ п╨п╬п╫я└п╦пЁя┐я─п╟я├п╦п╦). 12.48 - 12.49 -<%invoke:<п╦п╪я▐> <п©п╟я─п╟п╪1> <п©п╟я─п╟п╪2> ... <п©п╟я─п╟п╪N>%> 12.50 -п▓я▀п©п╬п╩п╫я▐п╣я┌ п╥п╟п©я─п╬я│ я│ п©п╟я─п╟п╪п╣я┌я─п╟п╪п╦ <п╦п╪я▐>.sql п╦ п╥п╟п╪п╣п╫я▐п╣я┌я│я▐ п╫п╟ я─п╣п╥я┐п╩я▄я┌п╟я┌я▀ п╬п╠я─п╟п╠п╬я┌п╨п╦ я┬п╟п╠п╩п╬п╫п╟ <п╦п╪я▐>.template. п≈п╫п╟я┤п╣п╫п╦я▐ п©п╟я─п╟п╪п╣я┌я─п╬п╡ п©п╬п╢я│я┌п╟п╡п╩я▐я▌я┌я│я▐ п╡ п╥п╟п©я─п╬я│ п╡п╪п╣я│я┌п╬ я│п╦п╪п╡п╬п╩п╟ '?'. 12.51 - 12.52 -<%image:<п╦я│я┘_я└п╟п╧п╩> <п╨п╬п╫_я└п╟п╧п╩> <я└п╬я─п╪п╟я┌> [<п╪п╟п╨я│_я┬п╦я─п╦п╫п╟>] [<п╪п╟п╨я│_п╡я▀я│п╬я┌п╟>]%> 12.53 -п≈п╟пЁя─я┐п╤п╟п╣я┌ п╦п╥п╬п╠я─п╟п╤п╣п╫п╦п╣ п╦п╥ я└п╟п╧п╩п╟ <п╦я│я┘_я└п╟п╧п╩> (п©я┐я┌я▄ п╬п©я─п╣п╢п╣п╩я▐п╣я┌я│я▐ п╬я┌п╫п╬я│п╦я┌п╣п╩я▄п╫п╬ п╨п╬п╫я└п╦пЁя┐я─п╟я├п╦п╬п╫п╫п╬пЁп╬ п©п╟я─п╟п╪п╣я┌я─п╟ "resource_base") п╦ п©я─п╣п╬п╠я─п╟п╥я┐п╣я┌ п╣пЁп╬ п╡ я┐п╨п╟п╥п╟п╫п╫я▀п╧ я└п╬я─п╪п╟я┌, я│п╬я┘я─п╟п╫я▐я▐ я─п╣п╥я┐п╩я▄я┌п╟я┌ п╡ <п╨п╬п╫_я└п╟п╧п╩>. п∙я│п╩п╦ п╥п╟п╢п╟п╫я▀ п╪п╟п╨я│п╦п╪п╟п╩я▄п╫п╟я▐ п╡я▀я│п╬я┌п╟ п╦ я┬п╦я─п╦п╫п╟, п╠п╬п╩я▄я┬п╦п╣ п╦п╥п╬п╠я─п╟п╤п╣п╫п╦я▐ п╠я┐п╢я┐я┌ я┐п╪п╣п╫я▄я┬п╣п╫я▀. 12.54 -п÷я─п╦ я┐я│п©п╣я┬п╫п╬п╪ п╡я▀п©п╬п╩п╫п╣п╫п╦п╦, п╦п╫я│я┌я─я┐п╨я├п╦я▐ "<%!image ...%>" п╠я┐п╢п╣я┌ п╥п╟п╪п╣п╫п╣п╫п╟ п╫п╟ п╥п╫п╟я┤п╣п╫п╦п╣ <п╨п╬п╫_я└п╟п╧п╩>, п╦п╫п╟я┤п╣ - п╫п╟ п©я┐я│я┌я┐я▌ я│я┌я─п╬п╨я┐. 12.55 - 12.56 -<%copy:<п╦я│я┘_я└п╟п╧п╩> <п╨п╬п╫_я└п╟п╧п╩>%> 12.57 -п п╬п©п╦я─я┐п╣я┌ я└п╟п╧п╩ <п╦я│я┘_я└п╟п╧п╩> (п©я┐я┌я▄ п╬п©я─п╣п╢п╣п╩я▐п╣я┌я│я▐ п╬я┌п╫п╬я│п╦я┌п╣п╩я▄п╫п╬ п╨п╬п╫я└п╦пЁя┐я─п╟я├п╦п╬п╫п╫п╬пЁп╬ п©п╟я─п╟п╪п╣я┌я─п╟ "resource_base"). 12.58 -п÷я─п╦ я┐я│п©п╣я┬п╫п╬п╪ п╡я▀п©п╬п╩п╫п╣п╫п╦п╦, п╦п╫я│я┌я─я┐п╨я├п╦я▐ "<%!copy ...%>" п╠я┐п╢п╣я┌ п╥п╟п╪п╣п╫п╣п╫п╟ п╫п╟ п╥п╫п╟я┤п╣п╫п╦п╣ <п╨п╬п╫_я└п╟п╧п╩>, п╦п╫п╟я┤п╣ - п╫п╟ п©я┐я│я┌я┐я▌ я│я┌я─п╬п╨я┐. 12.59 - 12.60 -п▓я│я┌я─п╬п╣п╫п╫я▀п╣ п©п╣я─п╣п╪п╣п╫п╫я▀п╣: 12.61 -NUMBER - п©п╬я─я▐п╢п╨п╬п╡я▀п╧ п╫п╬п╪п╣я─ я│я┌я─п╬п╨п╦ я─п╣п╥я┐п╩я▄я┌п╟я┌п╟ п╡я▀п©п╬п╩п╫п╣п╫п╦я▐ п╥п╟п©я─п╬я│п╟. 12.62 -п╖я┌п╬п╠я▀ п╬п╠я─п╟я┌п╦я┌я▄я│я▐ п╨ п©п╣я─п╣п╪п╣п╫п╫п╬п╧ п╥п╟п©я─п╬я│п╟, п╦п╥ п╨п╬я┌п╬я─п╬пЁп╬ п╬п╠я─п╟п╠п╟я┌я▀п╡п╟п╣п╪я▀п╧ я┬п╟п╠п╩п╬п╫ п╠я▀п╩ п╡я▀п╥п╡п╟п╫ я│ п©п╬п╪п╬я┴я▄я▌ я└я┐п╫п╨я├п╦п╦ invoke, п©п╣я─п╣п╢ п╦п╪п╣п╫п╣п╪ п©п╣я─п╣п╪п╣п╫п╫п╬п╧ п╫я┐п╤п╫п╬ п╢п╬п╠п╟п╡п╦я┌я▄ "SUPER." (п╫п╟п©я─п╦п╪п╣я─: "SUPER.NUMBER"). 12.63 - 12.64 -п÷я─п╦п╪п╣я─: 12.65 -п║п╩п╣п╢я┐я▌я┴п╟я▐ п╦п╫я│я┌я─я┐п╨я├п╦я▐ п©п╬п╩я┐я┤п╦я┌ п╥п╫п╟я┤п╣п╫п╦п╣ п╦п╥ я│я┌п╬п╩п╠я├п╟ name п╦ п╥п╟п╪п╣п╫п╦я┌ п╡ п╫п╣п╪ я│п©п╣я├п╦п╟п╩я▄п╫я▀п╣ я│п╦п╪п╡п╬п╩я▀: 12.66 -<%escape get:name%>
13.1 --- a/dist/tema Tue May 16 18:04:09 2006 +0400 13.2 +++ b/dist/tema Thu Dec 14 23:22:05 2006 +0300 13.3 @@ -1,3 +1,3 @@ 13.4 #!/bin/sh 13.5 13.6 -java -jar tema.jar 13.7 +java -jar tema.jar "$@"
14.1 --- a/dist/tema.bat Tue May 16 18:04:09 2006 +0400 14.2 +++ b/dist/tema.bat Thu Dec 14 23:22:05 2006 +0300 14.3 @@ -1,1 +1,1 @@ 14.4 -java -jar tema.jar 14.5 +java -jar tema.jar %1
15.1 --- a/dist/tema.properties Tue May 16 18:04:09 2006 +0400 15.2 +++ b/dist/tema.properties Thu Dec 14 23:22:05 2006 +0300 15.3 @@ -9,14 +9,14 @@ 15.4 main_template : main.template 15.5 15.6 # File encodings 15.7 -# input_encoding : ISO-8859-5 15.8 -# output_encoding : ISO-8859-5 15.9 +# input_encoding : UTF-8 15.10 +# output_encoding : UTF-8 15.11 15.12 # Cache templates 15.13 -cache_read : true 15.14 +# cache_read : true 15.15 15.16 # Output main_template parsing result to stderr 15.17 -#output : stderr 15.18 +# output : stderr 15.19 15.20 # File to output error messages (redirect stderr) 15.21 -#log : tema.log 15.22 +# log : tema.log
16.1 --- a/doc/article.txt Tue May 16 18:04:09 2006 +0400 16.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 16.3 @@ -1,391 +0,0 @@ 16.4 -* Преобразование базы данных в XML-формат электронной библиотеки. 16.5 - 16.6 -Для решения задачи преобразования базы данных "Местообитания Восточной 16.7 -Фенноскандии" из формата Microsoft Access в XML-формат электронной 16.8 -библиотеки КарНЦ РАН была разработана программная система DbReader. 16.9 - 16.10 -Программа DbReader является универсальным средством для представления 16.11 -информации из баз данных в текстовых форматах. Программа обрабатывает 16.12 -заданные шаблоны текстовых файлов и заменяет найденные в них 16.13 -инструкции на результаты их выполнения. Различные инструкции позволяют 16.14 -формировать SQL-запросы, выполнять их и обрабатывать полученные 16.15 -данные. 16.16 - 16.17 - 16.18 -* Формат инструкций: 16.19 - 16.20 - <%<список_функций>{:|\}<данные>%> 16.21 - где 16.22 - 16.23 -<список_функций> - список имен функций, разделенных пробелами. 16.24 - Может быть пустым. 16.25 -<данные> - данные, передаваемые функции. 16.26 - 16.27 - 16.28 -* Формат данных: 16.29 - 16.30 - [<список_аргументов>][<текст>] 16.31 - где 16.32 - 16.33 -<список_аргументов> - список аргументов функции, разделенных пробелами. 16.34 - Может быть пустым. 16.35 -<текст> - текст, передаваемый функции без разбиения на аргументы. 16.36 - Может быть пустым. Количество аргументов, после которого следует 16.37 - текст, зависит от функции. 16.38 - 16.39 -Разделитель между списком функций и данными определяет, как должны 16.40 -обрабатываться данные функции: 16.41 -: - рекурсивная обработка, 16.42 -\ - передать без обработки. 16.43 - 16.44 -Если в списке функций задано две и более функции, они выполняются, 16.45 -начиная с последней, так что каждая функция получает в качестве данных 16.46 -результат выполнения следующей функции. 16.47 - 16.48 -Каждая функция имеет код возврата - целое число. Код возврата 16.49 -инструкции - код возврата первой в списке функции. Код возврата, 16.50 -получаемый при обработке текста - сумма кодов возврата обработанных 16.51 -инструкций. 16.52 - 16.53 -Вместо скобок '<', '>' можно использовать скобки '[', ']'. 16.54 - 16.55 - 16.56 -* Реализованные функции: 16.57 - 16.58 -Функция: set 16.59 -Аргументы: <имя> 16.60 -Текст: <значение> 16.61 -Действие: устанавливает значение переменной <имя> 16.62 -Результат: <имя> 16.63 -Код возврата: 1 16.64 - 16.65 -Функция: get 16.66 -Аргументы: <имя> 16.67 -Результат: значение переменной <имя>. 16.68 -Код возврата: 1, если значение переменной было установлено, 0 - иначе. 16.69 - 16.70 -Функция: prepare 16.71 -Аргументы: <имя> 16.72 -Текст: <запрос> 16.73 -Действие: Подготавливает SQL-запрос <запрос> для выполнения, 16.74 - записывает подготовленный запрос в переменную <имя>. 16.75 -Результат: <имя> 16.76 -Код возврата: 1 16.77 - 16.78 -Функция: query 16.79 -Аргументы: <имя_запроса> <шаблон> <парам1> ... <парамN> 16.80 -Действие: Выполняет запрос с параметрами, подготовленный с помощью 16.81 - функции prepare. Значения параметров подставляются в 16.82 - запрос вместо символа '?'. Значения полей ответа будут 16.83 - записаны, как переменные шаблона <шаблон>. При обработки 16.84 - шаблона <шаблон> также определяется переменная NUMBER, 16.85 - содержащая номер текущей строки ответа. Переменные, 16.86 - определенные в вызывающем шаблоне, доступны из шаблона 16.87 - <шаблон> по имени SUPER.<имя_переменной>. 16.88 - 16.89 -Результат: результат обработки шаблона <шаблон> для каждой строки 16.90 - ответа. 16.91 -Код возврата: количество полученных строк ответа. 16.92 - 16.93 -Функция: optional 16.94 -Текст: <данные> 16.95 -Результат: <данные>, если при обработке данных был получен 16.96 - код возврата отличный от 0, иначе - пустая строка. 16.97 -Код возврата: 1, если результат - пустая строка, 0 - иначе. 16.98 - 16.99 -Функция: image 16.100 -Аргументы: <исх_файл> <кон_файл> <формат> [<макс_ширина> [<макс_высота>]] 16.101 -Действие: Загружает изображение из файла <исх_файл> (путь определяется 16.102 - относительно конфигурационного параметра "resource_base") и 16.103 - преобразует его в указанный формат, сохраняя результат в 16.104 - <кон_файл>. Если заданы максимальная высота и ширина, большие 16.105 - изображения будут уменьшены. 16.106 -Результат: <кон_файл> при успешном выполнении, пустая строка - иначе. 16.107 -Код возврата: 1 при успешном выполнении, 0 - иначе. 16.108 - 16.109 -Функция: copy 16.110 -Аргументы: <исх_файл> <кон_файл> 16.111 -Действие: Копирует файл <исх_файл> в файл <кон_файл> 16.112 - (путь <исх_файл> определяется относительно 16.113 - конфигурационного параметра "resource_base"). 16.114 -Результат: <кон_файл> при успешном выполнении, пустая строка - иначе. 16.115 -Код возврата: 1 при успешном выполнении, 0 - иначе. 16.116 - 16.117 -Функция: write 16.118 -Аргументы: <имя_файла> 16.119 -Текст: <данные> 16.120 -Действие: Записывает <данные> в файл <исх_файл>. 16.121 -Результат: <кон_файл> при успешном выполнении, пустая строка - иначе. 16.122 -Код возврата: 1 при успешном выполнении, 0 - иначе. 16.123 - 16.124 -Функция: read 16.125 -Текст: <имя_файла> 16.126 -Действие: Читает файл <имя_файла>. 16.127 -Результат: прочитанные данные при успешном выполнении, пустая 16.128 - строка - иначе. 16.129 -Код возврата: 1 при успешном выполнении, 0 - иначе. 16.130 - 16.131 -Функция: include 16.132 -Текст: <имя_файла> 16.133 -Действие: включает шаблон из файла <имя_файла>. 16.134 -Результат: результат обработки шаблона. 16.135 -Код возврата: код возврата, полученный при обработке шаблона. 16.136 - 16.137 -Функция: ! 16.138 -Текст: <данные> 16.139 -Действие: нет. 16.140 -Результат: нет. 16.141 -Код возврата: код возврата, полученный при обработке текста данных. 16.142 - 16.143 -Функция: replace 16.144 -Аргументы: <стр1> <стр2> 16.145 -Текст: <данные> 16.146 -Результат: данные, с замененными вхождениями подстроки <стр1> 16.147 - на <стр2>. 16.148 -Код возврата: код возврата, полученный при обработке текста данных. 16.149 - 16.150 -Функция: xml_escape 16.151 -Текст: <данные> 16.152 -Результат: текст <данные>, в котором символы 16.153 - '&', '<', '>', '`', '\' заменены на соответствующие 16.154 - сущности XML. 16.155 -Код возврата: код возврата, полученный при обработке текста данных. 16.156 - 16.157 -Функция: xml_cdata 16.158 -Текст: <данные> 16.159 -Результат: данные в виде блока XML CDATA. 16.160 -Код возврата: код возврата, полученный при обработке текста данных. 16.161 - 16.162 -Система DbReader расширяема: возможно добавление в систему новых 16.163 -функций, реализованных в виде классов на языке Java. 16.164 - 16.165 - 16.166 -* Применение системы DbReader для преобразования базы данных 16.167 - "Местообитания Восточной Фенноскандии" из формата Microsoft Access в 16.168 - XML-формат электронной библиотеки КарНЦ РАН 16.169 - 16.170 -Для преобразования используются две таблицы базы данных "Местообитания 16.171 -Восточной Фенноскандии" (перечислены только используемые поля): 16.172 - 16.173 -biotopelist (code, rangcode, rusname, engname, descript, geobotdescr, 16.174 - contributors, descrdate) 16.175 - 16.176 - code - счетчик, ключевое поле; 16.177 - rangcode - поле в формате ABBCCDDEE, где А, BB, CC, DD, ЕЕ - коды 16.178 - класса, подклассов и растения; 16.179 - rusname, engname, descript, geobotdescr - текстовые поля; 16.180 - descrdate - дата. 16.181 - 16.182 -photos (biotope, photo, authphoto) 16.183 - 16.184 - biotope - число, указывает на code в biotopelist; 16.185 - photo - имя файла фотографии; 16.186 - authphoto - текст. 16.187 - 16.188 -Требуется сгенерировать xml-файл для каждой записи в biotopelist, файл 16.189 -со списком классов, файл со списком растений, полноразмерные и 16.190 -уменьшенные версии каждой фотографии. 16.191 - 16.192 -Для генерации xml-файлов с описаниями биотопов использовался следующий 16.193 -шаблон DbReader (файл biotope.template): 16.194 - 16.195 ----------------------------------------------------------------------- 16.196 -<?xml version="1.0" encoding="ISO-8859-5"?> 16.197 -<!DOCTYPE описание_вида SYSTEM "brief.dtd"> 16.198 -<!-- rangcode: <%xml_escape get\rangcode%> --> 16.199 -<описание_вида show="0"> 16.200 - <рисунки display="0"> 16.201 - <%optional:<карта_распространения номер="1" 16.202 - file="<%xml_escape image:maps/<%get\rangcode%>.gif maps/<%get\code%>.png png%>"/>%> 16.203 -<%query:photo_sql [%\<%include\photo.template%>%] <%get\code%>%> 16.204 - </рисунки> 16.205 - <название><%xml_escape get\rusname%></название> 16.206 - <класс><%xml_escape get\class0%></класс> 16.207 - <подкласс1><%xml_escape get\class1%></подкласс1> 16.208 - <подкласс2><%xml_escape get\class2%></подкласс2> 16.209 - <подкласс3><%xml_escape get\class3%></подкласс3> 16.210 - <краткая_характеристика rows="3"><%xml_cdata get\descript%></краткая_характеристика> 16.211 - <пример_описания rows="3"><%xml_cdata get\geobotdescr%></пример_описания> 16.212 - <авторы_описания><%xml_escape get\contributors%></авторы_описания> 16.213 -</описание_вида> 16.214 ----------------------------------------------------------------------- 16.215 - 16.216 -Соответствующий SQL-запрос, при выполнении которого устанавливаются 16.217 -значения переменных шаблона rangcode, rusname, class0, class1, class2, 16.218 -class3, descript, geobotdescr и contributors (файл biotope.sql): 16.219 - 16.220 ----------------------------------------------------------------------- 16.221 -SELECT t1.*, 16.222 - 16.223 -(SELECT t2.rusname FROM biotopelist AS t2 16.224 -WHERE Left(t2.rangcode, 1) = Left(t1.rangcode, 1) 16.225 -AND Right(t2.rangcode, 8) = '00000000' 16.226 -AND Right(t1.rangcode, 8) <> '00000000') AS class0, 16.227 - 16.228 -(SELECT t2.rusname FROM biotopelist AS t2 16.229 -WHERE Left(t2.rangcode, 3) = Left(t1.rangcode, 3) 16.230 -AND Right(t2.rangcode, 6) = '000000' 16.231 -AND Right(t1.rangcode, 6) <> '000000') AS class1, 16.232 - 16.233 -(SELECT t2.rusname FROM biotopelist AS t2 16.234 -WHERE Left(t2.rangcode, 5) = Left(t1.rangcode, 5) 16.235 -AND Right(t2.rangcode, 4) = '0000' 16.236 -AND Right(t1.rangcode, 4) <> '0000') AS class2, 16.237 - 16.238 -(SELECT t2.rusname FROM biotopelist AS t2 16.239 -WHERE Left(t2.rangcode, 7) = Left(t1.rangcode, 7) 16.240 -AND Right(t2.rangcode, 2) = '00' 16.241 -AND Right(t1.rangcode, 2) <> '00') AS class3 16.242 - 16.243 -FROM biotopelist AS t1 16.244 -WHERE rusname 16.245 ----------------------------------------------------------------------- 16.246 - 16.247 -Шаблон biotope.template содержит инструкцию <%include\photo.template%>, 16.248 -включающую шаблон описания фотографии (файл photo.template): 16.249 - 16.250 ----------------------------------------------------------------------- 16.251 - <фотография num="<%xml_escape get\NUMBER%>" 16.252 - <%optional:автор="<%xml_escape get\authphoto%>" %>text="" 16.253 - file="<%xml_escape image:biotopephotos/<%get\photo%> images/<%get\SUPER.code%>_<%get\NUMBER%>.jpg jpg 300 300%>" 16.254 - big="<%xml_escape copy:biotopephotos/<%get\photo%> images/big/<%get\SUPER.code%>_<%get\NUMBER%>.jpg%>"/> 16.255 ----------------------------------------------------------------------- 16.256 - 16.257 -Соответствующий SQL-запрос для получения описания фотографий 16.258 -(photo.sql): 16.259 - 16.260 ----------------------------------------------------------------------- 16.261 -SELECT * from photos WHERE biotope = ? 16.262 ----------------------------------------------------------------------- 16.263 - 16.264 -Шаблон, генерирующий список классов (файл classes.template): 16.265 - 16.266 ----------------------------------------------------------------------- 16.267 -<?xml version="1.0" encoding="ISO-8859-5"?> 16.268 -<классификация><%query:class_sql [%\ 16.269 - <!-- rangcode: <%xml_escape get\rangcode%> --> 16.270 - <класс id="<%get\NUMBER%>"><%xml_escape get\rusname%></класс>%]%> 16.271 -</классификация> 16.272 ----------------------------------------------------------------------- 16.273 - 16.274 -Соответствующий SQL-запрос (class.sql): 16.275 - 16.276 ----------------------------------------------------------------------- 16.277 -SELECT t1.* 16.278 -FROM biotopelist AS t1 16.279 -WHERE rusname AND Right(t1.rangcode, 8) = '00000000' 16.280 - AND EXISTS 16.281 - (SELECT NULL FROM biotopelist AS t2 16.282 - WHERE Left(t2.rangcode, 1) = Left(t1.rangcode, 1) 16.283 - AND Right(t2.rangcode, 8) <> '00000000') 16.284 ----------------------------------------------------------------------- 16.285 - 16.286 -Шаблон, генерирующий список растений (файл plants.template): 16.287 - 16.288 ----------------------------------------------------------------------- 16.289 -<?xml version="1.0" encoding="ISO-8859-5"?> 16.290 -<растения><%query:plant_sql [%\ 16.291 - <!-- rangcode: <%xml_escape get\rangcode%> --> 16.292 - <растение><%xml_escape get\rusname%></растение>%]%> 16.293 -</растения> 16.294 ----------------------------------------------------------------------- 16.295 - 16.296 -Соответствующий SQL-запрос (plant.sql): 16.297 - 16.298 ----------------------------------------------------------------------- 16.299 -SELECT t1.* 16.300 -FROM biotopelist AS t1 16.301 -WHERE rusname AND Right(t1.rangcode, 2) <> '00' 16.302 ----------------------------------------------------------------------- 16.303 - 16.304 -Система DbReader начинает работу с обработки шаблона index.template, 16.305 -который содержит вызовы перечисленных выше SQL-запросов и включения 16.306 -шаблонов: 16.307 - 16.308 ----------------------------------------------------------------------- 16.309 -<%!: 16.310 - <%prepare:biotope_sql <%read\biotope.sql%>%> 16.311 - <%prepare:photo_sql <%read\photo.sql%>%> 16.312 - <%prepare:class_sql <%read\class.sql%>%> 16.313 - <%prepare:plant_sql <%read\plant.sql%>%> 16.314 - 16.315 - <%query:biotope_sql [%\<%write:<%get\code%>.xml <%include\biotope.template%>%> %]%> 16.316 - 16.317 - <%write:classes.xml <%include\classes.template%>%> 16.318 - <%write:plants.xml <%include\plants.template%>%> 16.319 -%> 16.320 ----------------------------------------------------------------------- 16.321 - 16.322 -Пример сгенерированного XML-файла: 16.323 - 16.324 ----------------------------------------------------------------------- 16.325 -<?xml version="1.0" encoding="ISO-8859-5"?> 16.326 -<!DOCTYPE описание_вида SYSTEM "brief.dtd"> 16.327 -<!-- rangcode: E04020302 --> 16.328 -<описание_вида show="0"> 16.329 - <рисунки display="0"> 16.330 - <фотография num="1" автор="Крышень А.М." text="" 16.331 - file="images/3_1.jpg" 16.332 - big="images/big/3_1.jpg"/> 16.333 - <фотография num="2" автор="Крышень А.М." text="" 16.334 - file="images/3_2.jpg" 16.335 - big="images/big/3_2.jpg"/> 16.336 - </рисунки> 16.337 - <название>Betula sp. - Avenella flexuosa - Polytrichum commune</название> 16.338 - <класс>E. Суходольные местообитания</класс> 16.339 - <подкласс1>Автоморфные влажные</подкласс1> 16.340 - <подкласс2></подкласс2> 16.341 - <подкласс3></подкласс3> 16.342 - <краткая_характеристика rows="3"><![CDATA[Развиваются на луговиковых вырубках лесов черничного типа. Через 5 - 7 лет после рубки порослевая береза выходит из яруса травянистых растений, ее влияние сказывается, в первую очередь, на влажности почвы.]]></краткая_характеристика> 16.343 - <пример_описания rows="3"></пример_описания> 16.344 - <авторы_описания></авторы_описания> 16.345 -</описание_вида> 16.346 ----------------------------------------------------------------------- 16.347 - 16.348 - 16.349 -* Структура программы DbReader 16.350 - 16.351 -Программа DbReader написана на языке программирования Java и состоит 16.352 -из следующих основных классов: 16.353 - 16.354 -ru.karrc.dbreader.DbReader: cодержит точку входа программы. Загружает 16.355 -конфигурацию, устанавливает соединение с источником данных с помощью 16.356 -библиотеки JDBC, запускает обработку основного шаблона. 16.357 - 16.358 -ru.karrc.dbreader.TemplateParser: осуществляет разбор шаблона, 16.359 -обработку инструкций и вызов функций. 16.360 - 16.361 -ru.karrc.dbreader.Function: абстрактный класс. Реализации всех функций 16.362 -DbReader наследуют этот класс. 16.363 - 16.364 -ru.karrc.dbreader.FunctionDataParser: обработчик данных 16.365 -функции. Посволяет получить список аргументов и текст, передаваемый 16.366 -функции. При необходимости вызывает рекурсивную обработку данных с 16.367 -помощью TemplateParser. 16.368 - 16.369 -ru.karrc.dbreader.Functions: содержит реализации функций в виде 16.370 -анонимных классов, наследующих Function. 16.371 - 16.372 -ru.karrc.dbreader.TemplateParser: исключение, выбрасываемое в случае 16.373 -возникновения ошибки при обработке шаблона. 16.374 - 16.375 -Кроме того, реализовано несколько впомогательных классов, которые 16.376 -используются в реализациях функций системы. 16.377 - 16.378 - 16.379 -* Метрики реализованной программной системы. 16.380 - 16.381 -Количество файлов исходного кода: 8, 16.382 -Количество Java-классов (включая анонимные): 27, 16.383 -Общее количество строк исходного текста: 1311, 16.384 -Количество строк кода (исключая пустые строки и комментарии): 812, 16.385 -Количество строк комментариев: 180. 16.386 - 16.387 - 16.388 -* Заключение 16.389 - 16.390 -Автором была разработана программная система DbReader, которая 16.391 -является расширяемым и универсальным средством для представления 16.392 -информации из баз данных в текстовых форматах. С помощью системы 16.393 -DbReader база данных "Местообитания Восточной Фенноскандии" была 16.394 -переведена в XML-формат электронной библиотеки КарНЦ РАН.
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/doc/manual/index.html Thu Dec 14 23:22:05 2006 +0300 17.3 @@ -0,0 +1,358 @@ 17.4 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 17.5 + "DTD/xhtml1-transitional.dtd"> 17.6 + 17.7 +<html> 17.8 + 17.9 +<head> 17.10 + <title>п°п╟п╨я─п╬п©я─п╬я├п╣я│я│п╬я─ TEMA</title> 17.11 + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 17.12 +</head> 17.13 + 17.14 +<body> 17.15 +<h1>п°п╟п╨я─п╬п©я─п╬я├п╣я│я│п╬я─ TEMA</h1> 17.16 + 17.17 +п°п╟п╨я─п╬п©я─п╬я├п╣я│я│п╬я─ TEMA п╬п╠я─п╟п╠п╟я┌я▀п╡п╟п╣я┌ п╥п╟п╢п╟п╫п╫я▀п╣ я┬п╟п╠п╩п╬п╫я▀ я┌п╣п╨я│я┌п╬п╡я▀я┘ я└п╟п╧п╩п╬п╡ п╦ 17.18 +п╥п╟п╪п╣п╫я▐п╣я┌ п╫п╟п╧п╢п╣п╫п╫я▀п╣ п╡ п╫п╦я┘ п╦п╫я│я┌я─я┐п╨я├п╦п╦ п╫п╟ я─п╣п╥я┐п╩я▄я┌п╟я┌я▀ п╦я┘ п╡я▀п©п╬п╩п╫п╣п╫п╦я▐. 17.19 + 17.20 +<p><b>п╓п╬я─п╪п╟я┌ п╦п╫я│я┌я─я┐п╨я├п╦п╧</b></p> 17.21 + 17.22 +<blockquote> 17.23 + <code><%<i>я│п©п╦я│п╬п╨_я└я┐п╫п╨я├п╦п╧</i>{:|\|`}<i>п╢п╟п╫п╫я▀п╣</i>%></code> 17.24 +</blockquote> 17.25 +<p> 17.26 +пЁп╢п╣<br /> 17.27 + 17.28 +<code><i>я│п©п╦я│п╬п╨_я└я┐п╫п╨я├п╦п╧</i></code> - я│п©п╦я│п╬п╨ п╦п╪п╣п╫ я└я┐п╫п╨я├п╦п╧, я─п╟п╥п╢п╣п╩п╣п╫п╫я▀я┘ 17.29 + п©я─п╬п╠п╣п╩п╟п╪п╦. п°п╬п╤п╣я┌ п╠я▀я┌я▄ п©я┐я│я┌я▀п╪.<br /> 17.30 +<code><i>п╢п╟п╫п╫я▀п╣</i></code> - п╢п╟п╫п╫я▀п╣, п©п╣я─п╣п╢п╟п╡п╟п╣п╪я▀п╣ я└я┐п╫п╨я├п╦п╦. 17.31 +</p> 17.32 + 17.33 +<p><b>п╓п╬я─п╪п╟я┌ п╢п╟п╫п╫я▀я┘</b></p> 17.34 + 17.35 +<blockquote> 17.36 + <code> 17.37 + [<i>я│п©п╦я│п╬п╨_п╟я─пЁя┐п╪п╣п╫я┌п╬п╡</i>][<i>я┌п╣п╨я│я┌</i>] 17.38 + </code> 17.39 +</blockquote> 17.40 +<p> 17.41 +пЁп╢п╣<br /> 17.42 + 17.43 +<code><i>я│п©п╦я│п╬п╨_п╟я─пЁя┐п╪п╣п╫я┌п╬п╡</i></code> - я│п©п╦я│п╬п╨ п╟я─пЁя┐п╪п╣п╫я┌п╬п╡ я└я┐п╫п╨я├п╦п╦, я─п╟п╥п╢п╣п╩п╣п╫п╫я▀я┘ п©я─п╬п╠п╣п╩п╟п╪п╦. 17.44 + п°п╬п╤п╣я┌ п╠я▀я┌я▄ п©я┐я│я┌я▀п╪.<br /> 17.45 +<code><i>я┌п╣п╨я│я┌</i></code> - я┌п╣п╨я│я┌, п©п╣я─п╣п╢п╟п╡п╟п╣п╪я▀п╧ я└я┐п╫п╨я├п╦п╦ п╠п╣п╥ я─п╟п╥п╠п╦п╣п╫п╦я▐ п╫п╟ п╟я─пЁя┐п╪п╣п╫я┌я▀. 17.46 + п°п╬п╤п╣я┌ п╠я▀я┌я▄ п©я┐я│я┌я▀п╪. п п╬п╩п╦я┤п╣я│я┌п╡п╬ п╟я─пЁя┐п╪п╣п╫я┌п╬п╡, п©п╬я│п╩п╣ п╨п╬я┌п╬я─п╬пЁп╬ я│п╩п╣п╢я┐п╣я┌ 17.47 + я┌п╣п╨я│я┌, п╥п╟п╡п╦я│п╦я┌ п╬я┌ я└я┐п╫п╨я├п╦п╦. 17.48 +</p><p> 17.49 +п═п╟п╥п╢п╣п╩п╦я┌п╣п╩я▄ п╪п╣п╤п╢я┐ я│п©п╦я│п╨п╬п╪ я└я┐п╫п╨я├п╦п╧ п╦ п╢п╟п╫п╫я▀п╪п╦ п╬п©я─п╣п╢п╣п╩я▐п╣я┌, п╨п╟п╨ п╢п╬п╩п╤п╫я▀ 17.50 +п╬п╠я─п╟п╠п╟я┌я▀п╡п╟я┌я▄я│я▐ п╢п╟п╫п╫я▀п╣ я└я┐п╫п╨я├п╦п╦: 17.51 +</p><p> 17.52 +<code>:</code> - я─п╣п╨я┐я─я│п╦п╡п╫п╟я▐ п╬п╠я─п╟п╠п╬я┌п╨п╟,<br /> 17.53 +<code>\</code> п╦п╩п╦ <code>`</code> - п©п╣я─п╣п╢п╟я┌я▄ п╠п╣п╥ п╬п╠я─п╟п╠п╬я┌п╨п╦. 17.54 +</p><p> 17.55 +п∙я│п╩п╦ п╡ я│п©п╦я│п╨п╣ я└я┐п╫п╨я├п╦п╧ п╥п╟п╢п╟п╫п╬ п╢п╡п╣ п╦ п╠п╬п╩п╣п╣ я└я┐п╫п╨я├п╦п╦, п╬п╫п╦ п╡я▀п©п╬п╩п╫я▐я▌я┌я│я▐, 17.56 +п╫п╟я┤п╦п╫п╟я▐ я│ п©п╬я│п╩п╣п╢п╫п╣п╧, я┌п╟п╨ я┤я┌п╬ п╨п╟п╤п╢п╟я▐ я└я┐п╫п╨я├п╦я▐ п©п╬п╩я┐я┤п╟п╣я┌ п╡ п╨п╟я┤п╣я│я┌п╡п╣ п╢п╟п╫п╫я▀я┘ 17.57 +я─п╣п╥я┐п╩я▄я┌п╟я┌ п╡я▀п©п╬п╩п╫п╣п╫п╦я▐ я│п╩п╣п╢я┐я▌я┴п╣п╧ я└я┐п╫п╨я├п╦п╦. 17.58 +</p><p> 17.59 +п п╟п╤п╢п╟я▐ я└я┐п╫п╨я├п╦я▐ п╦п╪п╣п╣я┌ п╨п╬п╢ п╡п╬п╥п╡я─п╟я┌п╟ - я├п╣п╩п╬п╣ я┤п╦я│п╩п╬. п п╬п╢ п╡п╬п╥п╡я─п╟я┌п╟ 17.60 +п╦п╫я│я┌я─я┐п╨я├п╦п╦ - п╨п╬п╢ п╡п╬п╥п╡я─п╟я┌п╟ п©п╣я─п╡п╬п╧ п╡ я│п©п╦я│п╨п╣ я└я┐п╫п╨я├п╦п╦. п п╬п╢ п╡п╬п╥п╡я─п╟я┌п╟, 17.61 +п©п╬п╩я┐я┤п╟п╣п╪я▀п╧ п©я─п╦ п╬п╠я─п╟п╠п╬я┌п╨п╣ я┌п╣п╨я│я┌п╟ - я│я┐п╪п╪п╟ п╨п╬п╢п╬п╡ п╡п╬п╥п╡я─п╟я┌п╟ п╬п╠я─п╟п╠п╬я┌п╟п╫п╫я▀я┘ 17.62 +п╦п╫я│я┌я─я┐п╨я├п╦п╧ (п╨п╟п╨ п©я─п╟п╡п╦п╩п╬, я│п╪я▀я│п╩ я█я┌п╬пЁп╬ п╥п╫п╟я┤п╣п╫п╦я▐ - п╨п╬п╩п╦я┤п╣я│я┌п╡п╬ п╦п╫я│я┌я─я┐п╨я├п╦п╧, 17.63 +п╥п╟п╪п╣п╫п╣п╫п╫я▀я┘ п╫п╟ п╫п╣п©я┐я│я┌п╬п╧ я┌п╣п╨я│я┌). 17.64 +</p><p> 17.65 +п я─п╬п╪п╣ я│п╨п╬п╠п╬п╨ '<', '>', п╪п╬п╤п╫п╬ п╦я│п©п╬п╩я▄п╥п╬п╡п╟я┌я▄ я│п╨п╬п╠п╨п╦ '[', ']'. 17.66 +</p> 17.67 + 17.68 + 17.69 +<h2>п╓я┐п╫п╨я├п╦п╦</h2> 17.70 + 17.71 +<p><code><b>set</b></code></p> 17.72 + 17.73 +<table> 17.74 +<tr><td>п░я─пЁя┐п╪п╣п╫я┌я▀:</td> 17.75 +<td><i>п╦п╪я▐</i></td></tr> 17.76 + 17.77 +<tr><td>п╒п╣п╨я│я┌:</td> 17.78 +<td><i>п╥п╫п╟я┤п╣п╫п╦п╣</i></td></tr> 17.79 + 17.80 +<tr><td>п■п╣п╧я│я┌п╡п╦п╣:</td> 17.81 +<td>пёя│я┌п╟п╫п╟п╡п╩п╦п╡п╟п╣я┌ п╥п╫п╟я┤п╣п╫п╦п╣ п©п╣я─п╣п╪п╣п╫п╫п╬п╧ <i>п╦п╪я▐</i>.</td></tr> 17.82 + 17.83 +<tr><td>п═п╣п╥я┐п╩я▄я┌п╟я┌:</td> 17.84 +<td><i>п╦п╪я▐</i></td></tr> 17.85 + 17.86 +<tr><td>п п╬п╢ п╡п╬п╥п╡я─п╟я┌п╟:</td> 17.87 +<td>1</td></tr> 17.88 +</table> 17.89 + 17.90 +<p><code><b>define</b></code></p> 17.91 + 17.92 +<table> 17.93 +<tr><td>п░я─пЁя┐п╪п╣п╫я┌я▀:</td> 17.94 +<td><i>п╦п╪я▐</i></td></tr> 17.95 + 17.96 +<tr><td>п╒п╣п╨я│я┌:</td> 17.97 +<td><i>я┬п╟п╠п╩п╬п╫</i></td></tr> 17.98 + 17.99 +<tr><td>п■п╣п╧я│я┌п╡п╦п╣:</td><td>п·п©я─п╣п╢п╣п╩я▐п╣я┌ п╫п╬п╡я┐я▌ я└я┐п╫п╨я├п╦я▌ <i>п╦п╪я▐</i>, п©я─п╦ 17.100 +п╡я▀п╥п╬п╡п╣ п╨п╬я┌п╬я─п╬п╧ п╬п╠я─п╟п╠п╟я┌я▀п╡п╟п╣я┌я│я▐ <i>я┬п╟п╠п╩п╬п╫</i>. п÷я─п╦ п╬п╠я─п╟п╠п╬я┌п╨п╣ п╢п╬я│я┌я┐п©п╫я▀ 17.101 +я└я┐п╫п╨я├п╦п╦ <code>nextarg</code> п╢п╩я▐ п©п╬п╩я┐я┤п╣п╫п╦я▐ п╬я┤п╣я─п╣п╢п╫п╬пЁп╬ п╟я─пЁя┐п╪п╣п╫я┌п╟ 17.102 +п╡я▀п╥я▀п╡п╟п╣п╪п╬п╧ я└я┐п╫п╨я├п╦п╦ п╦ <code>data</code> п╢п╩я▐ п©п╬п╩я┐я┤п╣п╫п╦я▐ я┌п╣п╨я│я┌п╟.</td></tr> 17.103 + 17.104 +<tr><td>п═п╣п╥я┐п╩я▄я┌п╟я┌:</td> 17.105 +<td><i>п╦п╪я▐</i></td></tr> 17.106 + 17.107 +<tr><td>п п╬п╢ п╡п╬п╥п╡я─п╟я┌п╟:</td> 17.108 +<td>1</td></tr> 17.109 +</table> 17.110 + 17.111 +<p><code><b>load</b></code></p> 17.112 + 17.113 +<table> 17.114 +<tr><td>п░я─пЁя┐п╪п╣п╫я┌я▀:</td> 17.115 +<td><i>п╦п╪я▐</i> <i>п╦п╪я▐_п╨п╩п╟я│я│п╟</i></td></tr> 17.116 + 17.117 +<tr><td>п■п╣п╧я│я┌п╡п╦п╣:</td> 17.118 + 17.119 +<td>п·п©я─п╣п╢п╣п╩я▐п╣я┌ п╫п╬п╡я┐я▌ я└я┐п╫п╨я├п╦я▌ <i>п╦п╪я▐</i>. п═п╣п╟п╩п╦п╥п╟я├п╦я▐ я└я┐п╫п╨я├п╦п╦ п╬п©я─п╣п╢п╣п╩п╣п╫п╟ 17.120 +Java-п╨п╩п╟я│я│п╬п╪ <i>п╦п╪я▐_п╨п╩п╟я│я│п╟</i>, п╫п╟я│п╩п╣п╢я┐я▌я┴п╦п╪ п╨п╩п╟я│я│ 17.121 +<code>kryshen.tema.Function</code>.</td></tr> 17.122 + 17.123 +<tr><td>п═п╣п╥я┐п╩я▄я┌п╟я┌:</td> 17.124 +<td><i>п╦п╪я▐</i></td></tr> 17.125 + 17.126 +<tr><td>п п╬п╢ п╡п╬п╥п╡я─п╟я┌п╟:</td> 17.127 +<td>1</td></tr> 17.128 +</table> 17.129 + 17.130 +<p><code><b>prepare</b></code></p> 17.131 + 17.132 +<table> 17.133 +<tr><td>п░я─пЁя┐п╪п╣п╫я┌я▀:</td> 17.134 +<td><i>п╦п╪я▐</i></td></tr> 17.135 + 17.136 +<tr><td>п╒п╣п╨я│я┌:</td> 17.137 +<td><i>п╥п╟п©я─п╬я│</i></td></tr> 17.138 + 17.139 +<tr><td>п■п╣п╧я│я┌п╡п╦п╣:</td> 17.140 +<td>п÷п╬п╢пЁп╬я┌п╟п╡п╩п╦п╡п╟п╣я┌ SQL-п╥п╟п©я─п╬я│ <i>п╥п╟п©я─п╬я│</i> п╢п╩я▐ п╡я▀п©п╬п╩п╫п╣п╫п╦я▐, п╥п╟п©п╦я│я▀п╡п╟п╣я┌ 17.141 +п©п╬п╢пЁп╬я┌п╬п╡п╩п╣п╫п╫я▀п╧ п╥п╟п©я─п╬я│ п╡ п©п╣я─п╣п╪п╣п╫п╫я┐я▌ <i>п╦п╪я▐</i>.</td></tr> 17.142 + 17.143 +<tr><td>п═п╣п╥я┐п╩я▄я┌п╟я┌:</td> 17.144 +<td><i>п╦п╪я▐</i></td></tr> 17.145 + 17.146 +<tr><td>п п╬п╢ п╡п╬п╥п╡я─п╟я┌п╟:</td> 17.147 +<td>1</td></tr> 17.148 +</table> 17.149 + 17.150 +<p><code><b>query</b></code></p> 17.151 + 17.152 +<table> 17.153 +<tr><td>п░я─пЁя┐п╪п╣п╫я┌я▀:</td> 17.154 +<td><i>п╦п╪я▐_п╥п╟п©я─п╬я│п╟</i> <i>я┬п╟п╠п╩п╬п╫</i> <i>п©п╟я─п╟п╪1</i> ... <i>п©п╟я─п╟п╪N</i></td></tr> 17.155 + 17.156 +<tr><td>п■п╣п╧я│я┌п╡п╦п╣:</td> 17.157 +<td>п▓я▀п©п╬п╩п╫я▐п╣я┌ п╥п╟п©я─п╬я│ я│ п©п╟я─п╟п╪п╣я┌я─п╟п╪п╦, п©п╬п╢пЁп╬я┌п╬п╡п╩п╣п╫п╫я▀п╧ я│ п©п╬п╪п╬я┴я▄я▌ я└я┐п╫п╨я├п╦п╦ 17.158 +prepare. п≈п╫п╟я┤п╣п╫п╦я▐ п©п╟я─п╟п╪п╣я┌я─п╬п╡ п©п╬п╢я│я┌п╟п╡п╩я▐я▌я┌я│я▐ п╡ п╥п╟п©я─п╬я│ п╡п╪п╣я│я┌п╬ я│п╦п╪п╡п╬п╩п╟ 17.159 +'?'. п≈п╫п╟я┤п╣п╫п╦я▐ п©п╬п╩п╣п╧ п╬я┌п╡п╣я┌п╟ п╢п╬я│я┌я┐п©п╫я▀ я│ п©п╬п╪п╬я┴я▄я▌ я└я┐п╫п╨я├п╦п╦ <code>db</code>, 17.160 +п╨п╟п╨ п©п╣я─п╣п╪п╣п╫п╫я▀п╣ я┬п╟п╠п╩п╬п╫п╟ <i>я┬п╟п╠п╩п╬п╫</i>. п÷я─п╦ п╬п╠я─п╟п╠п╬я┌п╨п╦ я┬п╟п╠п╩п╬п╫п╟ я┌п╟п╨п╤п╣ 17.161 +п╬п©я─п╣п╢п╣п╩я▐п╣я┌я│я▐ п©п╣я─п╣п╪п╣п╫п╫п╟я▐ <code>number</code>, я│п╬п╢п╣я─п╤п╟я┴п╟я▐ п╫п╬п╪п╣я─ я┌п╣п╨я┐я┴п╣п╧ 17.162 +я│я┌я─п╬п╨п╦ п╬я┌п╡п╣я┌п╟.</td></tr> 17.163 + 17.164 +<tr><td>п═п╣п╥я┐п╩я▄я┌п╟я┌:</td> 17.165 +<td>я─п╣п╥я┐п╩я▄я┌п╟я┌ п╬п╠я─п╟п╠п╬я┌п╨п╦ я┬п╟п╠п╩п╬п╫п╟ <i>я┬п╟п╠п╩п╬п╫</i> п╢п╩я▐ п╨п╟п╤п╢п╬п╧ я│я┌я─п╬п╨п╦ 17.166 +п╬я┌п╡п╣я┌п╟.</td></tr> 17.167 + 17.168 +<tr><td>п п╬п╢ п╡п╬п╥п╡я─п╟я┌п╟:</td> 17.169 +<td>п п╬п╩п╦я┤п╣я│я┌п╡п╬ п©п╬п╩я┐я┤п╣п╫п╫я▀я┘ я│я┌я─п╬п╨ п╬я┌п╡п╣я┌п╟.</td></tr> 17.170 +</table> 17.171 + 17.172 +<p><code><b>optional</b></code></p> 17.173 + 17.174 +<table> 17.175 +<tr><td>п╒п╣п╨я│я┌:</td> 17.176 +<td><i>п╢п╟п╫п╫я▀п╣</i></td></tr> 17.177 + 17.178 +<tr><td>п═п╣п╥я┐п╩я▄я┌п╟я┌:</td><td><i>п╢п╟п╫п╫я▀п╣</i>, п╣я│п╩п╦ п©я─п╦ п╬п╠я─п╟п╠п╬я┌п╨п╣ п╢п╟п╫п╫я▀я┘ 17.179 +п╠я▀п╩ п©п╬п╩я┐я┤п╣п╫ п╨п╬п╢ п╡п╬п╥п╡я─п╟я┌п╟ п╬я┌п╩п╦я┤п╫я▀п╧ п╬я┌ 0, п╦п╫п╟я┤п╣ - п©я┐я│я┌п╟я▐ 17.180 +я│я┌я─п╬п╨п╟.</td></tr> 17.181 + 17.182 +<tr><td>п п╬п╢ п╡п╬п╥п╡я─п╟я┌п╟:</td> 17.183 +<td>1, п╣я│п╩п╦ я─п╣п╥я┐п╩я▄я┌п╟я┌ - п©я┐я│я┌п╟я▐ я│я┌я─п╬п╨п╟, 0 - п╦п╫п╟я┤п╣.</td></tr> 17.184 +</table> 17.185 + 17.186 +<p><code><b>image</b></code></p> 17.187 + 17.188 +<table> 17.189 +<tr><td>п░я─пЁя┐п╪п╣п╫я┌я▀:</td> 17.190 +<td><i>п╦я│я┘_я└п╟п╧п╩</i> <i>п╨п╬п╫_я└п╟п╧п╩</i> <i>я└п╬я─п╪п╟я┌</i> [<i>п╪п╟п╨я│_я┬п╦я─п╦п╫п╟</i> 17.191 +[<i>п╪п╟п╨я│_п╡я▀я│п╬я┌п╟</i>]]</td></tr> 17.192 + 17.193 +<tr><td>п■п╣п╧я│я┌п╡п╦п╣:</td> 17.194 +<td>п≈п╟пЁя─я┐п╤п╟п╣я┌ п╦п╥п╬п╠я─п╟п╤п╣п╫п╦п╣ п╦п╥ я└п╟п╧п╩п╟ <i>п╦я│я┘_я└п╟п╧п╩</i> (п©я┐я┌я▄ п╬п©я─п╣п╢п╣п╩я▐п╣я┌я│я▐ 17.195 +п╬я┌п╫п╬я│п╦я┌п╣п╩я▄п╫п╬ п╨п╬п╫я└п╦пЁя┐я─п╟я├п╦п╬п╫п╫п╬пЁп╬ п©п╟я─п╟п╪п╣я┌я─п╟ "resource_base") п╦ 17.196 +п©я─п╣п╬п╠я─п╟п╥я┐п╣я┌ п╣пЁп╬ п╡ я┐п╨п╟п╥п╟п╫п╫я▀п╧ я└п╬я─п╪п╟я┌, я│п╬я┘я─п╟п╫я▐я▐ я─п╣п╥я┐п╩я▄я┌п╟я┌ п╡ 17.197 +<i>п╨п╬п╫_я└п╟п╧п╩</i>. п∙я│п╩п╦ п╥п╟п╢п╟п╫я▀ п╪п╟п╨я│п╦п╪п╟п╩я▄п╫п╟я▐ п╡я▀я│п╬я┌п╟ п╦ я┬п╦я─п╦п╫п╟, п╠п╬п╩я▄я┬п╦п╣ 17.198 +п╦п╥п╬п╠я─п╟п╤п╣п╫п╦я▐ п╠я┐п╢я┐я┌ я┐п╪п╣п╫я▄я┬п╣п╫я▀.</td></tr> 17.199 + 17.200 +<tr><td>п═п╣п╥я┐п╩я▄я┌п╟я┌:</td> 17.201 +<td><i>п╨п╬п╫_я└п╟п╧п╩</i> п©я─п╦ я┐я│п©п╣я┬п╫п╬п╪ п╡я▀п©п╬п╩п╫п╣п╫п╦п╦, п©я┐я│я┌п╟я▐ я│я┌я─п╬п╨п╟ - п╦п╫п╟я┤п╣.</td></tr> 17.202 + 17.203 +<tr><td>п п╬п╢ п╡п╬п╥п╡я─п╟я┌п╟:</td> 17.204 +<td>1 п©я─п╦ я┐я│п©п╣я┬п╫п╬п╪ п╡я▀п©п╬п╩п╫п╣п╫п╦п╦, 0 - п╦п╫п╟я┤п╣.</td></tr> 17.205 +</table> 17.206 + 17.207 + 17.208 +<p><code><b>copy</b></code></p> 17.209 + 17.210 +<table> 17.211 +<tr><td>п░я─пЁя┐п╪п╣п╫я┌я▀:</td><td><i>п╦я│я┘_я└п╟п╧п╩</i> <i>п╨п╬п╫_я└п╟п╧п╩</i></td></tr> 17.212 + 17.213 +<tr><td>п■п╣п╧я│я┌п╡п╦п╣:</td><td>п п╬п©п╦я─я┐п╣я┌ я└п╟п╧п╩ <i>п╦я│я┘_я└п╟п╧п╩</i> п╡ я└п╟п╧п╩ 17.214 +<i>п╨п╬п╫_я└п╟п╧п╩</i> (п©я┐я┌я▄ <i>п╦я│я┘_я└п╟п╧п╩</i> п╬п©я─п╣п╢п╣п╩я▐п╣я┌я│я▐ п╬я┌п╫п╬я│п╦я┌п╣п╩я▄п╫п╬ 17.215 +п╨п╬п╫я└п╦пЁя┐я─п╟я├п╦п╬п╫п╫п╬пЁп╬ п©п╟я─п╟п╪п╣я┌я─п╟ "resource_base").</td></tr> 17.216 + 17.217 +<tr><td>п═п╣п╥я┐п╩я▄я┌п╟я┌:</td><td><i>п╨п╬п╫_я└п╟п╧п╩</i> п©я─п╦ я┐я│п©п╣я┬п╫п╬п╪ п╡я▀п©п╬п╩п╫п╣п╫п╦п╦, 17.218 +п©я┐я│я┌п╟я▐ я│я┌я─п╬п╨п╟ - п╦п╫п╟я┤п╣.</td></tr> 17.219 + 17.220 +<tr><td>п п╬п╢ п╡п╬п╥п╡я─п╟я┌п╟:</td><td>1 п©я─п╦ я┐я│п©п╣я┬п╫п╬п╪ п╡я▀п©п╬п╩п╫п╣п╫п╦п╦, 0 - 17.221 +п╦п╫п╟я┤п╣.</td></tr> 17.222 +</table> 17.223 + 17.224 +<p><code><b>write</b></code></p> 17.225 + 17.226 +<table> 17.227 +<tr><td>п░я─пЁя┐п╪п╣п╫я┌я▀:</td><td><i>п╦п╪я▐_я└п╟п╧п╩п╟</i></td></tr> 17.228 + 17.229 +<tr><td>п╒п╣п╨я│я┌:</td><td><i>п╢п╟п╫п╫я▀п╣</i></td></tr> 17.230 + 17.231 +<tr><td>п■п╣п╧я│я┌п╡п╦п╣:</td><td>п≈п╟п©п╦я│я▀п╡п╟п╣я┌ <i>п╢п╟п╫п╫я▀п╣</i> п╡ я└п╟п╧п╩ 17.232 +<i>п╦я│я┘_я└п╟п╧п╩</i>.</td></tr> 17.233 + 17.234 +<tr><td>п═п╣п╥я┐п╩я▄я┌п╟я┌:</td><td><i>п╨п╬п╫_я└п╟п╧п╩</i> п©я─п╦ я┐я│п©п╣я┬п╫п╬п╪ п╡я▀п©п╬п╩п╫п╣п╫п╦п╦, 17.235 +п©я┐я│я┌п╟я▐ я│я┌я─п╬п╨п╟ - п╦п╫п╟я┤п╣.</td></tr> 17.236 + 17.237 +<tr><td>п п╬п╢ п╡п╬п╥п╡я─п╟я┌п╟:</td><td>1 п©я─п╦ я┐я│п©п╣я┬п╫п╬п╪ п╡я▀п©п╬п╩п╫п╣п╫п╦п╦, 0 - 17.238 +п╦п╫п╟я┤п╣.</td></tr> 17.239 +</table> 17.240 + 17.241 +<p><code><b>read</b></code></p> 17.242 + 17.243 +<table> 17.244 +<tr><td>п╒п╣п╨я│я┌:</td><td><i>п╦п╪я▐_я└п╟п╧п╩п╟</i></td></tr> 17.245 +<tr><td>п■п╣п╧я│я┌п╡п╦п╣:</td><td>п╖п╦я┌п╟п╣я┌ я└п╟п╧п╩ <i>п╦п╪я▐_я└п╟п╧п╩п╟</i>.</td></tr> 17.246 +<tr><td>п═п╣п╥я┐п╩я▄я┌п╟я┌:</td><td>п©я─п╬я┤п╦я┌п╟п╫п╫я▀п╣ п╢п╟п╫п╫я▀п╣ п©я─п╦ я┐я│п©п╣я┬п╫п╬п╪ п╡я▀п©п╬п╩п╫п╣п╫п╦п╦, 17.247 + п©я┐я│я┌п╟я▐ я│я┌я─п╬п╨п╟ - п╦п╫п╟я┤п╣.</td></tr> 17.248 +<tr><td>п п╬п╢ п╡п╬п╥п╡я─п╟я┌п╟:</td><td>1 п©я─п╦ я┐я│п©п╣я┬п╫п╬п╪ п╡я▀п©п╬п╩п╫п╣п╫п╦п╦, 0 - 17.249 +п╦п╫п╟я┤п╣.</td></tr> 17.250 +</table> 17.251 + 17.252 +<p><code><b>include</b></code></p> 17.253 + 17.254 +<table> 17.255 +<tr><td>п╒п╣п╨я│я┌:</td><td><i>п╦п╪я▐_я└п╟п╧п╩п╟</i></td></tr> 17.256 +<tr><td>п■п╣п╧я│я┌п╡п╦п╣:</td><td>п╡п╨п╩я▌я┤п╟п╣я┌ я┬п╟п╠п╩п╬п╫ п╦п╥ я└п╟п╧п╩п╟ 17.257 +<i>п╦п╪я▐_я└п╟п╧п╩п╟</i>.</td></tr> 17.258 +<tr><td>п═п╣п╥я┐п╩я▄я┌п╟я┌:</td><td>я─п╣п╥я┐п╩я▄я┌п╟я┌ п╬п╠я─п╟п╠п╬я┌п╨п╦ я┬п╟п╠п╩п╬п╫п╟.</td></tr> 17.259 +<tr><td>п п╬п╢ п╡п╬п╥п╡я─п╟я┌п╟:</td><td>п╨п╬п╢ п╡п╬п╥п╡я─п╟я┌п╟, п©п╬п╩я┐я┤п╣п╫п╫я▀п╧ п©я─п╦ п╬п╠я─п╟п╠п╬я┌п╨п╣ 17.260 +я┬п╟п╠п╩п╬п╫п╟.</td></tr> 17.261 +</table> 17.262 + 17.263 +<p><code><b>!</b></code></p> 17.264 + 17.265 +<table> 17.266 +<tr><td>п╒п╣п╨я│я┌:</td><td><i>п╢п╟п╫п╫я▀п╣</i></td></tr> 17.267 + 17.268 +<tr><td>п■п╣п╧я│я┌п╡п╦п╣:</td><td>п╫п╣я┌.</td></tr> 17.269 + 17.270 +<tr><td>п═п╣п╥я┐п╩я▄я┌п╟я┌:</td><td>п╫п╣я┌.</td></tr> 17.271 + 17.272 +<tr><td>п п╬п╢ п╡п╬п╥п╡я─п╟я┌п╟:</td><td>п╨п╬п╢ п╡п╬п╥п╡я─п╟я┌п╟, п©п╬п╩я┐я┤п╣п╫п╫я▀п╧ п©я─п╦ п╬п╠я─п╟п╠п╬я┌п╨п╣ 17.273 +я┌п╣п╨я│я┌п╟ п╢п╟п╫п╫я▀я┘.</td></tr> 17.274 +</table> 17.275 + 17.276 +<p><code><b>replace</b></code></p> 17.277 + 17.278 +<table> 17.279 +<tr><td>п░я─пЁя┐п╪п╣п╫я┌я▀:</td><td><i>я│я┌я─1</i> <i>я│я┌я─2</i></td></tr> 17.280 + 17.281 +<tr><td>п╒п╣п╨я│я┌:</td><td><i>п╢п╟п╫п╫я▀п╣</i></td></tr> 17.282 + 17.283 +<tr><td>п═п╣п╥я┐п╩я▄я┌п╟я┌:</td><td>п╢п╟п╫п╫я▀п╣, я│ п╥п╟п╪п╣п╫п╣п╫п╫я▀п╪п╦ п╡я┘п╬п╤п╢п╣п╫п╦я▐п╪п╦ п©п╬п╢я│я┌я─п╬п╨п╦ 17.284 +<i>я│я┌я─1</i> п╫п╟ <i>я│я┌я─2</i>.</td></tr> 17.285 + 17.286 +<tr><td>п п╬п╢ п╡п╬п╥п╡я─п╟я┌п╟:</td><td> п╨п╬п╢ п╡п╬п╥п╡я─п╟я┌п╟, п©п╬п╩я┐я┤п╣п╫п╫я▀п╧ п©я─п╦ п╬п╠я─п╟п╠п╬я┌п╨п╣ 17.287 +я┌п╣п╨я│я┌п╟ п╢п╟п╫п╫я▀я┘.</td></tr> 17.288 +</table> 17.289 + 17.290 +<p><code><b>xml_escape</b></code></p> 17.291 + 17.292 +<table> 17.293 +<tr><td>п╒п╣п╨я│я┌:</td><td><i>п╢п╟п╫п╫я▀п╣</i></td></tr> 17.294 +<tr><td>п═п╣п╥я┐п╩я▄я┌п╟я┌:</td><td>я┌п╣п╨я│я┌ <i>п╢п╟п╫п╫я▀п╣</i>, п╡ п╨п╬я┌п╬я─п╬п╪ я│п╦п╪п╡п╬п╩я▀ 17.295 +'&', '<', '>', '`', '\' п╥п╟п╪п╣п╫п╣п╫я▀ п╫п╟ я│п╬п╬я┌п╡п╣я┌я│я┌п╡я┐я▌я┴п╦п╣ я│я┐я┴п╫п╬я│я┌п╦ 17.296 +XML.</td></tr> 17.297 + 17.298 +<tr><td>п п╬п╢ п╡п╬п╥п╡я─п╟я┌п╟:</td><td> п╨п╬п╢ п╡п╬п╥п╡я─п╟я┌п╟, п©п╬п╩я┐я┤п╣п╫п╫я▀п╧ п©я─п╦ п╬п╠я─п╟п╠п╬я┌п╨п╣ 17.299 +я┌п╣п╨я│я┌п╟ п╢п╟п╫п╫я▀я┘.</td></tr> 17.300 +</table> 17.301 + 17.302 +<p><code><b>xml_cdata</b></code></p> 17.303 + 17.304 +<table> 17.305 +<tr><td>п╒п╣п╨я│я┌:</td><td><i>п╢п╟п╫п╫я▀п╣</i></td></tr> 17.306 + 17.307 +<tr><td>п═п╣п╥я┐п╩я▄я┌п╟я┌:</td><td>п╢п╟п╫п╫я▀п╣ п╡ п╡п╦п╢п╣ п╠п╩п╬п╨п╟ XML CDATA.</td></tr> 17.308 + 17.309 +<tr><td>п п╬п╢ п╡п╬п╥п╡я─п╟я┌п╟:</td><td> п╨п╬п╢ п╡п╬п╥п╡я─п╟я┌п╟, п©п╬п╩я┐я┤п╣п╫п╫я▀п╧ п©я─п╦ п╬п╠я─п╟п╠п╬я┌п╨п╣ 17.310 +я┌п╣п╨я│я┌п╟ п╢п╟п╫п╫я▀я┘. </td></tr> 17.311 +</table> 17.312 + 17.313 +<p> 17.314 +п°п╟п╨я─п╬п©я─п╬я├п╣я│я│п╬я─ TEMA я─п╟я│я┬п╦я─я▐п╣п╪: п╡п╬п╥п╪п╬п╤п╫п╬ п╢п╬п╠п╟п╡п╩п╣п╫п╦п╣ п╡ я│п╦я│я┌п╣п╪я┐ п╫п╬п╡я▀я┘ 17.315 +я└я┐п╫п╨я├п╦п╧, я─п╣п╟п╩п╦п╥п╬п╡п╟п╫п╫я▀я┘ п╡ п╡п╦п╢п╣ п╨п╩п╟я│я│п╬п╡ п╫п╟ я▐п╥я▀п╨п╣ Java. 17.316 +</p> 17.317 + 17.318 +<h2>п≈п╟п©я┐я│п╨</h2> 17.319 + 17.320 +<p>java -jar tema.jar [<i>п╬п©я├п╦п╦</i>] 17.321 +</p><p> 17.322 +п·п©я├п╦п╦: 17.323 +</p> 17.324 +<table> 17.325 +<tr><td>-d[emo]</td><td>п■п╣п╪п╬п╫я│я┌я─п╟я├п╦п╬п╫п╫я▀п╧ я─п╣п╤п╦п╪</td></tr> 17.326 +<tr><td>-v[ersion]</td><td>п▓я▀п╡п╬п╢ п╡п╣я─я│п╦п╦</td></tr> 17.327 +<tr><td>-h[help] -u[sage]</td><td>п▓я▀п╡п╬п╢ я│п©я─п╟п╡п╨п╦</td></tr> 17.328 +</table> 17.329 + 17.330 +<p> 17.331 +п÷я─п╦ п╥п╟п©я┐я│п╨п╣ я┤п╦я┌п╟п╣я┌я│я▐ я└п╟п╧п╩ "tema.properties" п╦п╥ я┌п╣п╨я┐я┴п╣пЁп╬ п╨п╟я┌п╟п╩п╬пЁп╟.<br /> 17.332 +п÷я─п╦п╪п╣я─ я└п╟п╧п╩п╟ "tema.properties": 17.333 +</p> 17.334 + 17.335 +<pre> 17.336 +# п²п╟я│я┌я─п╬п╧п╨п╟ п╦я│я┌п╬я┤п╫п╦п╨п╟ п╢п╟п╫п╫я▀я┘ 17.337 +# resource : jdbc:odbc:database 17.338 +# driver : sun.jdbc.odbc.JdbcOdbcDriver 17.339 + 17.340 +# п▒п╟п╥п╬п╡я▀п╧ п╨п╟я┌п╟п╩п╬пЁ я─п╣я│я┐я─я│п╬п╡ 17.341 +# resource_base : . 17.342 + 17.343 +# п╗п╟п╠п╩п╬п╫, я│ п╨п╬я┌п╬я─п╬пЁп╬ п╫п╟я┤п╦п╫п╟п╣я┌я│я▐ п╬п╠я─п╟п╠п╬я┌п╨п╟ 17.344 +main_template : main.template 17.345 + 17.346 +# п п╬п╢п╦я─п╬п╡п╨п╦ я└п╟п╧п╩п╬п╡ 17.347 +# input_encoding : UTF-8 17.348 +# output_encoding : UTF-8 17.349 + 17.350 +# п я█я┬п╦я─п╬п╡п╟п╫п╦п╣ я┬п╟п╠п╩п╬п╫п╬п╡ 17.351 +# cache_read : true 17.352 + 17.353 +# п▓я▀п╡п╬п╢ я─п╣п╥я┐п╩я▄я┌п╟я┌п╟ я─п╟п╥п╠п╬я─п╟ я┬п╟п╠п╩п╬п╫п╟ main.template п╡ stderr 17.354 +# output : stderr 17.355 + 17.356 +# п▓я▀п╡п╬п╢ я│п╬п╬п╠я┴п╣п╫п╦п╧ п╬п╠ п╬я┬п╦п╠п╨п╟я┘ п╡ я└п╟п╧п╩ 17.357 +# log : dbreader.log 17.358 +</pre> 17.359 + 17.360 +</body> 17.361 +</html>
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/res/kryshen/tema/demo/demo.template Thu Dec 14 23:22:05 2006 +0300 18.3 @@ -0,0 +1,25 @@ 18.4 +[%!\ TEMA demo template %] 18.5 + 18.6 +п▓я▀п╡п╬п╢ я┌п╣п╨я│я┌п╟: 18.7 +test text 18.8 + 18.9 +п▓я▀п╡п╬п╢ я│п©п╣я├п╦п╟п╩я▄п╫я▀я┘ я│п╦п╪п╡п╬п╩п╬п╡: 18.10 +[%\<%test%>%] 18.11 + 18.12 +п·п╠я┼я▐п╡п╩п╣п╫п╦п╣ я└я┐п╫п╨я├п╦п╦: 18.13 +<%define\test test arg1:[%nextarg:%], test arg2:[%nextarg:%], test data:[%data:%].%> 18.14 + 18.15 +п▓я▀п╥п╬п╡ п╫п╬п╡п╬п╧ я└я┐п╫п╨я├п╦п╦: 18.16 +<%test:1 2 3%> 18.17 + 18.18 +п≈п╟пЁя─я┐п╥п╨п╟ я└я┐п╫п╨я├п╦п╦ п╦п╥ п╨п╩п╟я│я│п╟: 18.19 +<%load\hello kryshen.tema.demo.Hello%> 18.20 + 18.21 +п▓я▀п©п╬п╩п╣п╫п╣п╫п╦п╣ п╥п╟пЁя─я┐п╤п╣п╫п╫п╬п╧ я└я┐п╫п╨я├п╦п╦: 18.22 +<%hello\TEMA%> 18.23 + 18.24 +пёя│п╩п╬п╡п╫п╬п╣ п╡я▀п©п╬п╩п╫п╣п╫п╦п╣: 18.25 +<%optional:<%true:%>True%> <%optional:<%false:%>False%> 18.26 + 18.27 +п╒п╣я│я┌п╦я─п╬п╡п╟п╫п╦п╣ xml_escape: 18.28 +<%xml_escape\x < a & b%>
19.1 --- a/sample/class.xml Tue May 16 18:04:09 2006 +0400 19.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 19.3 @@ -1,9 +0,0 @@ 19.4 -<?xml version="1.0" encoding="ISO-8859-5"?> 19.5 -<зшпААьДьзпФьО> 19.6 - <зшпАА id="1">╟щБЮчъчсущщКу эуАБччяьБпщьО</зшпАА> 19.7 - <зшпАА id="2">╪чЮО ь эчЮАзьу ъчяуЮужЛО</зшпАА> 19.8 - <зшпАА id="3">╬вуЮп ь ъЮьяЮужщКу эуАБччяьБпщьО</зшпАА> 19.9 - <зшпАА id="4">юузь, ЮЦГЛь ь ъЮьяЮужщКу эуАБччяьБпщьО</зшпАА> 19.10 - <зшпАА id="5">╠чшчБп ь впячшчГущщКу вуэшь</зшпАА> 19.11 - <зшпАА id="6">аЦЕчтчшЛщКу эуАБччяьБпщьО</зшпАА> 19.12 -</зшпААьДьзпФьО>
20.1 --- a/sample/plants.xml Tue May 16 18:04:09 2006 +0400 20.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 20.3 @@ -1,6 +0,0 @@ 20.4 -<?xml version="1.0" encoding="ISO-8859-5"?> 20.5 -<ЮпАБущьО> 20.6 - <ЮпАБущьу>Betula sp.</ЮпАБущьу> 20.7 - <ЮпАБущьу>Calamagrostis arundinacea</ЮпАБущьу> 20.8 - <ЮпАБущьу>Geranium sylvaticum</ЮпАБущьу> 20.9 -</ЮпАБущьО>
21.1 --- a/src/kryshen/tema/Function.java Tue May 16 18:04:09 2006 +0400 21.2 +++ b/src/kryshen/tema/Function.java Thu Dec 14 23:22:05 2006 +0300 21.3 @@ -1,7 +1,21 @@ 21.4 /* 21.5 - * Copyright (C) 2005, 2006 Mikhail A. Kryshen 21.6 + * Copyright (C) 2005, 2006 Mikhail A. Kryshen 21.7 * 21.8 - * $Id: Function.java,v 1.1.1.1 2006/05/16 14:04:09 mikhail Exp $ 21.9 + * This program is free software; you can redistribute it and/or modify 21.10 + * it under the terms of the GNU General Public License as published by 21.11 + * the Free Software Foundation; either version 2 of the License, or 21.12 + * (at your option) any later version. 21.13 + * 21.14 + * This program is distributed in the hope that it will be useful, 21.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 21.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21.17 + * GNU General Public License for more details. 21.18 + * 21.19 + * You should have received a copy of the GNU General Public License 21.20 + * along with this program; if not, write to the Free Software 21.21 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21.22 + * 21.23 + * $Id: Function.java,v 1.5 2006/12/14 14:39:22 mikhail Exp $ 21.24 */ 21.25 21.26 package kryshen.tema; 21.27 @@ -10,13 +24,19 @@ 21.28 import java.util.*; 21.29 import java.sql.ResultSet; 21.30 21.31 +/** 21.32 + * Abstact class for TEMA functions. 21.33 + * 21.34 + * @author Mikhail A. Kryshen 21.35 + */ 21.36 public abstract class Function { 21.37 - public final String name; 21.38 21.39 - protected Function(String name) { 21.40 - this.name = name; 21.41 - } 21.42 - 21.43 + /** 21.44 + * Invoke the function. 21.45 + * 21.46 + * @param fdp FunctionDataParser to access function arguments. 21.47 + * @param out Writer for the function output. 21.48 + */ 21.49 public abstract int invoke(FunctionDataParser fdp, Writer out) 21.50 throws IOException, TemplateException; 21.51 }
22.1 --- a/src/kryshen/tema/FunctionDataParser.java Tue May 16 18:04:09 2006 +0400 22.2 +++ b/src/kryshen/tema/FunctionDataParser.java Thu Dec 14 23:22:05 2006 +0300 22.3 @@ -1,7 +1,21 @@ 22.4 /* 22.5 - * Copyright (C) 2006 Mikhail A. Kryshen 22.6 + * Copyright (C) 2006 Mikhail A. Kryshen 22.7 * 22.8 - * $Id: FunctionDataParser.java,v 1.1.1.1 2006/05/16 14:04:09 mikhail Exp $ 22.9 + * This program is free software; you can redistribute it and/or modify 22.10 + * it under the terms of the GNU General Public License as published by 22.11 + * the Free Software Foundation; either version 2 of the License, or 22.12 + * (at your option) any later version. 22.13 + * 22.14 + * This program is distributed in the hope that it will be useful, 22.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 22.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22.17 + * GNU General Public License for more details. 22.18 + * 22.19 + * You should have received a copy of the GNU General Public License 22.20 + * along with this program; if not, write to the Free Software 22.21 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22.22 + * 22.23 + * $Id: FunctionDataParser.java,v 1.5 2006/12/14 14:39:22 mikhail Exp $ 22.24 */ 22.25 22.26 package kryshen.tema; 22.27 @@ -23,13 +37,13 @@ 22.28 22.29 private TemplateParser tp; 22.30 private FunctionData fd; 22.31 - private Reader in; 22.32 + private TemplateReader in; 22.33 22.34 private boolean available = true; 22.35 private boolean first = true; 22.36 22.37 FunctionDataParser(TemplateParser tp, FunctionData fd, 22.38 - Reader in) { 22.39 + TemplateReader in) { 22.40 this.tp = tp; 22.41 this.fd = fd; 22.42 this.in = in; 22.43 @@ -40,7 +54,7 @@ 22.44 22.45 if (!available) 22.46 throw new TemplateException 22.47 - ("Unexpected end of instruction data."); 22.48 + ("Unexpected end of instruction data.", in); 22.49 22.50 TemplateParser.Result r; 22.51 22.52 @@ -53,11 +67,11 @@ 22.53 argument ? ARG_SEPARATORS : null, 22.54 (argument || !first) ? ARG_SEPARATORS : null); 22.55 } else if (fd == FunctionData.SUBFUNCTION && argument) { 22.56 - /* Subfunction can pass a list of arguments */ 22.57 + // Subfunction can pass a list of arguments 22.58 StringWriter sw = new StringWriter(); 22.59 tp.parseFunction(in, sw); 22.60 sw.close(); 22.61 - in = new StringReader(sw.toString()); 22.62 + in = new TemplateReader(new StringReader(sw.toString()), in); 22.63 fd = FunctionData.NONRECURSIVE; 22.64 r = parseData(out, true); 22.65 } else if (fd == FunctionData.SUBFUNCTION) { 22.66 @@ -74,7 +88,7 @@ 22.67 } 22.68 22.69 public int parseData(Writer out) throws IOException, TemplateException { 22.70 - return parseData(out, false).substitutions; 22.71 + return parseData(out, false).retCode; 22.72 } 22.73 22.74 public String getData() throws IOException, TemplateException { 22.75 @@ -92,7 +106,7 @@ 22.76 r = parseData(out, true); 22.77 } 22.78 22.79 - return r.substitutions; 22.80 + return r.retCode; 22.81 } 22.82 22.83 public String getNextArg() throws IOException, TemplateException { 22.84 @@ -119,4 +133,8 @@ 22.85 public TemplateParser getTemplateParser() { 22.86 return tp; 22.87 } 22.88 + 22.89 + public TemplateReader getTemplateReader() { 22.90 + return in; 22.91 + } 22.92 }
23.1 --- a/src/kryshen/tema/Functions.java Tue May 16 18:04:09 2006 +0400 23.2 +++ b/src/kryshen/tema/Functions.java Thu Dec 14 23:22:05 2006 +0300 23.3 @@ -1,7 +1,21 @@ 23.4 /* 23.5 - * Copyright (C) 2005, 2006 Mikhail A. Kryshen 23.6 + * Copyright (C) 2005, 2006 Mikhail A. Kryshen 23.7 * 23.8 - * $Id: Functions.java,v 1.1.1.1 2006/05/16 14:04:09 mikhail Exp $ 23.9 + * This program is free software; you can redistribute it and/or modify 23.10 + * it under the terms of the GNU General Public License as published by 23.11 + * the Free Software Foundation; either version 2 of the License, or 23.12 + * (at your option) any later version. 23.13 + * 23.14 + * This program is distributed in the hope that it will be useful, 23.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 23.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23.17 + * GNU General Public License for more details. 23.18 + * 23.19 + * You should have received a copy of the GNU General Public License 23.20 + * along with this program; if not, write to the Free Software 23.21 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23.22 + * 23.23 + * $Id: Functions.java,v 1.11 2006/12/14 19:44:31 mikhail Exp $ 23.24 */ 23.25 23.26 package kryshen.tema; 23.27 @@ -9,328 +23,48 @@ 23.28 import java.io.*; 23.29 import java.util.*; 23.30 23.31 -import java.sql.SQLException; 23.32 -import java.sql.PreparedStatement; 23.33 - 23.34 import kryshen.tema.functions.*; 23.35 23.36 +/** 23.37 + * Standard TEMA functions. 23.38 + * 23.39 + * @author Mikhail A. Kryshen 23.40 + */ 23.41 public class Functions { 23.42 - public static final Function GET = 23.43 - new Function("get") { 23.44 - public int invoke(FunctionDataParser fdp, Writer out) 23.45 - throws IOException, TemplateException { 23.46 + // TODO: arithmetics, conditions 23.47 23.48 - String name = fdp.getData(); 23.49 - return fdp.getTemplateParser().parseVariable(name, out); 23.50 - } 23.51 - }; 23.52 + /** 23.53 + * Register all standard functions. 23.54 + * 23.55 + * @param p TemplateParser to register functions in. 23.56 + */ 23.57 + static void registerAllFunctions(TemplateParser p) { 23.58 + p.registerFunction("!", Standard.NULL_OUTPUT); 23.59 + p.registerFunction("set", Standard.SET); 23.60 + p.registerFunction("load", Standard.LOAD); 23.61 + p.registerFunction("query", Standard.QUERY); 23.62 + p.registerFunction("prepare", Standard.PREPARE); 23.63 + p.registerFunction("replace", Standard.REPLACE); 23.64 + p.registerFunction("xml_escape", Standard.XML_ESCAPE); 23.65 + p.registerFunction("xml_cdata", Standard.XML_CDATA); 23.66 23.67 - public static final Function SET = 23.68 - new Function("set") { 23.69 - public int invoke(FunctionDataParser fdp, Writer out) 23.70 - throws IOException, TemplateException { 23.71 + p.registerFunction("define", Define.DEFINE); 23.72 23.73 - String arg0 = fdp.getNextArg(); 23.74 - String arg1 = fdp.getData(); 23.75 - 23.76 - fdp.getTemplateParser().setValue(arg0, arg1); 23.77 - 23.78 - out.write(arg0); 23.79 - return 1; 23.80 - } 23.81 - }; 23.82 + p.registerFunction("write", IO.WRITE); 23.83 + p.registerFunction("read", IO.READ); 23.84 + p.registerFunction("include", IO.INCLUDE); 23.85 + p.registerFunction("copy", IO.COPY); 23.86 23.87 - /* prepare:qury_name sql_statement */ 23.88 - public static final Function PREPARE = 23.89 - new Function("prepare") { 23.90 - public int invoke(FunctionDataParser fdp, Writer out) 23.91 - throws IOException, TemplateException { 23.92 + p.registerFunction("false", Logics.FALSE); 23.93 + p.registerFunction("true", Logics.TRUE); 23.94 + p.registerFunction("optional", Logics.OPTIONAL); 23.95 23.96 - String arg0 = fdp.getNextArg(); 23.97 - String data = fdp.getData(); 23.98 + p.registerFunction("image", ImageConverter.IMAGE); 23.99 23.100 - PreparedStatement statement; 23.101 - 23.102 - try { 23.103 - statement = Tema.connection.prepareStatement(data); 23.104 - } catch (SQLException e) { 23.105 - throw new TemplateException(e.getMessage(), e); 23.106 - } 23.107 - 23.108 - fdp.getTemplateParser().setValue(arg0, statement); 23.109 - 23.110 - out.write(arg0); 23.111 - return 1; 23.112 - } 23.113 - }; 23.114 - 23.115 - public static final Function OPTIONAL = 23.116 - new Function("optional") { 23.117 - public int invoke(FunctionDataParser fdp, Writer out) 23.118 - throws IOException, TemplateException { 23.119 - 23.120 - StringWriter sw = new StringWriter(); 23.121 - int s = fdp.parseData(sw); 23.122 - sw.close(); 23.123 - String data = sw.toString(); 23.124 - 23.125 - if (s > 0) { 23.126 - out.write(data); 23.127 - return 1; 23.128 - } else { 23.129 - return 0; 23.130 - } 23.131 - } 23.132 - }; 23.133 - 23.134 - public static final Function IMAGE = 23.135 - new Function("image") { 23.136 - public int invoke(FunctionDataParser fdp, Writer out) 23.137 - throws IOException, TemplateException { 23.138 - 23.139 - String arg0 = fdp.getNextArg(); 23.140 - String arg1 = fdp.getNextArg(); 23.141 - String arg2 = fdp.getNextArg(); 23.142 - int arg3 = fdp.hasMoreData() ? 23.143 - Integer.parseInt(fdp.getNextArg()) : -1; 23.144 - int arg4 = fdp.hasMoreData() ? 23.145 - Integer.parseInt(fdp.getNextArg()) : -1; 23.146 - 23.147 - File source = new File 23.148 - (Tema.getProperty("resource_base"), arg0); 23.149 - 23.150 - try { 23.151 - ImageConverter.convert 23.152 - (source, /* source file */ 23.153 - new File(arg1), /* dest file */ 23.154 - arg2, /* format */ 23.155 - arg3, /* max width */ 23.156 - arg4); /* max height */ 23.157 - } catch (Exception e) { 23.158 - System.err.println(e); 23.159 - return 0; 23.160 - } 23.161 - 23.162 - out.write(arg1); 23.163 - return 1; 23.164 - } 23.165 - }; 23.166 - 23.167 - public static final Function COPY = 23.168 - new Function("copy") { 23.169 - public int invoke(FunctionDataParser fdp, Writer out) 23.170 - throws IOException, TemplateException { 23.171 - 23.172 - String arg0 = fdp.getNextArg(); 23.173 - String arg1 = fdp.getNextArg(); 23.174 - 23.175 - File source = new File 23.176 - (Tema.getProperty("resource_base"), arg0); 23.177 - File dest = new File(arg1); 23.178 - 23.179 - try { 23.180 - copyFile(source, dest); 23.181 - } catch (IOException e) { 23.182 - System.err.println(e); 23.183 - return 0; 23.184 - } 23.185 - out.write(arg1); 23.186 - return 1; 23.187 - } 23.188 - }; 23.189 - 23.190 - /* query:sql_query template arg1 arg2 ... argN */ 23.191 - public static final Function QUERY = 23.192 - new Function("query") { 23.193 - public int invoke(FunctionDataParser fdp, Writer out) 23.194 - throws IOException, TemplateException { 23.195 - 23.196 - String arg0 = fdp.getNextArg(); 23.197 - String arg1 = fdp.getNextArg(); 23.198 - List<String> args = fdp.getArgs(); 23.199 - 23.200 - TemplateParser tp = fdp.getTemplateParser(); 23.201 - 23.202 - try { 23.203 - return Tema.query 23.204 - (arg1, (PreparedStatement)tp.getValue(arg0), 23.205 - args, tp, out); 23.206 - } catch (SQLException e) { 23.207 - throw new TemplateException(e.getMessage(), e); 23.208 - } 23.209 - } 23.210 - }; 23.211 - 23.212 - public static final Function WRITE = 23.213 - new Function("write") { 23.214 - public int invoke(FunctionDataParser fdp, Writer out) 23.215 - throws IOException, TemplateException { 23.216 - 23.217 - String arg0 = fdp.getNextArg(); 23.218 - 23.219 - System.err.println("Writing " + arg0 + "..."); 23.220 - 23.221 - Writer fw; 23.222 - 23.223 - try { 23.224 - fw = Tema.createFileWriter(arg0); 23.225 - } catch (IOException e) { 23.226 - System.err.println(e); 23.227 - return 0; 23.228 - } 23.229 - 23.230 - try { 23.231 - fdp.parseData(fw); 23.232 - } finally { 23.233 - fw.close(); 23.234 - } 23.235 - 23.236 - out.write(arg0); 23.237 - 23.238 - System.err.println("Saved " + arg0 + "."); 23.239 - return 1; 23.240 - } 23.241 - }; 23.242 - 23.243 - public static final Function READ = 23.244 - new Function("read") { 23.245 - public int invoke(FunctionDataParser fdp, Writer out) 23.246 - throws IOException, TemplateException { 23.247 - 23.248 - String filename = fdp.getData(); 23.249 - String file; 23.250 - 23.251 - try { 23.252 - file = Tema.readFile(new File(filename)); 23.253 - } catch (IOException e) { 23.254 - System.err.println(e); 23.255 - return 0; 23.256 - } 23.257 - 23.258 - out.write(file); 23.259 - return 1; 23.260 - } 23.261 - }; 23.262 - 23.263 - public static final Function INCLUDE = 23.264 - new Function("include") { 23.265 - public int invoke(FunctionDataParser fdp, Writer out) 23.266 - throws IOException, TemplateException { 23.267 - 23.268 - String filename = fdp.getData(); 23.269 - 23.270 - Reader fin = new BufferedReader 23.271 - (Tema.createCachedFileReader(new File(filename))); 23.272 - 23.273 - int r = fdp.getTemplateParser().parse(fin, out); 23.274 - 23.275 - fin.close(); 23.276 - return r; 23.277 - } 23.278 - }; 23.279 - 23.280 - public static final Function NULL_OUTPUT = 23.281 - new Function("!") { 23.282 - public int invoke(FunctionDataParser fdp, Writer out) 23.283 - throws IOException, TemplateException { 23.284 - 23.285 - /* Write nothing. */ 23.286 - return fdp.parseData(new Writer() { 23.287 - public void close() {} 23.288 - public void flush() {} 23.289 - public void write(char[] cbuf, int off, int len) {} 23.290 - }); 23.291 - } 23.292 - }; 23.293 - 23.294 - public static final Function REPLACE = 23.295 - new Function("replace") { 23.296 - public int invoke(FunctionDataParser fdp, Writer out) 23.297 - throws IOException, TemplateException { 23.298 - 23.299 - String arg0 = fdp.getNextArg(); 23.300 - String arg1 = fdp.getNextArg(); 23.301 - 23.302 - ReplaceWriter rw = new ReplaceWriter(out, arg0, arg1); 23.303 - 23.304 - int ret = fdp.parseData(rw); 23.305 - rw.finish(); 23.306 - return ret; 23.307 - } 23.308 - }; 23.309 - 23.310 - public static final Function XML_ESCAPE = 23.311 - new Function("xml_escape") { 23.312 - public int invoke(FunctionDataParser fdp, Writer out) 23.313 - throws IOException, TemplateException { 23.314 - 23.315 - final String[] chars = {"&", "<", ">", "`", "\""}; 23.316 - final String[] escape = {"&", "<", ">", "'", """}; 23.317 - 23.318 - ReplaceWriter rw = new ReplaceWriter(out, chars, escape); 23.319 - 23.320 - int ret = fdp.parseData(rw); 23.321 - rw.finish(); 23.322 - return ret; 23.323 - } 23.324 - }; 23.325 - 23.326 - public static final Function XML_CDATA = 23.327 - new Function("xml_cdata") { 23.328 - public int invoke(FunctionDataParser fdp, Writer out) 23.329 - throws IOException, TemplateException { 23.330 - 23.331 - ReplaceWriter rw = new ReplaceWriter 23.332 - (out, "]]>", "]]]><![CDATA[]>", "<![CDATA[", "]]>"); 23.333 - 23.334 - int ret = fdp.parseData(rw); 23.335 - rw.finish(); 23.336 - return ret; 23.337 - } 23.338 - }; 23.339 - 23.340 - public static final Function DEFINE = new Define(); 23.341 - 23.342 - private static void copyFile(File src, File dest) throws IOException { 23.343 - System.err.print("Copying " + src + "... "); 23.344 - 23.345 - if (src.lastModified() < dest.lastModified()) { 23.346 - System.err.println(dest + " is up to date."); 23.347 - return; 23.348 - } 23.349 - 23.350 - File parent = dest.getParentFile(); 23.351 - if (parent != null) parent.mkdirs(); 23.352 - 23.353 - InputStream in = new FileInputStream(src); 23.354 - OutputStream out = new FileOutputStream(dest); 23.355 - 23.356 - byte[] buffer = new byte[1024]; 23.357 - int len; 23.358 - while ((len = in.read(buffer)) > 0) { 23.359 - out.write(buffer, 0, len); 23.360 - } 23.361 - in.close(); 23.362 - out.close(); 23.363 - 23.364 - System.err.println("saved " + dest + "."); 23.365 - } 23.366 - 23.367 - static void registerAllFunctions(TemplateParser p) { 23.368 - p.registerFunction(GET); 23.369 - p.registerFunction(SET); 23.370 - p.registerFunction(OPTIONAL); 23.371 - p.registerFunction(IMAGE); 23.372 - p.registerFunction(COPY); 23.373 - p.registerFunction(QUERY); 23.374 - p.registerFunction(PREPARE); 23.375 - p.registerFunction(WRITE); 23.376 - p.registerFunction(READ); 23.377 - p.registerFunction(INCLUDE); 23.378 - p.registerFunction(NULL_OUTPUT); 23.379 - p.registerFunction(REPLACE); 23.380 - p.registerFunction(XML_ESCAPE); 23.381 - p.registerFunction(XML_CDATA); 23.382 - p.registerFunction(DEFINE); 23.383 + /* 23.384 + Other functuons: 23.385 + db - defined in Tema.query(). 23.386 + nextarg, data - defined in Define.invoke(). 23.387 + */ 23.388 } 23.389 }
24.1 --- a/src/kryshen/tema/ImageConverter.java Tue May 16 18:04:09 2006 +0400 24.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 24.3 @@ -1,184 +0,0 @@ 24.4 -/* 24.5 - * Copyright (C) 2005, 2006 Mikhail A. Kryshen 24.6 - * 24.7 - * $Id: ImageConverter.java,v 1.1.1.1 2006/05/16 14:04:09 mikhail Exp $ 24.8 - */ 24.9 - 24.10 -package kryshen.tema; 24.11 - 24.12 -import java.util.*; 24.13 -import java.io.*; 24.14 -import java.awt.*; 24.15 -import java.awt.image.*; 24.16 -import java.awt.geom.AffineTransform; 24.17 -import javax.imageio.*; 24.18 -import javax.imageio.stream.*; 24.19 - 24.20 -/** 24.21 - * Class defines static method to convert images to specified format. 24.22 - * 24.23 - * @author Mikhail A. Kryshen 24.24 - */ 24.25 -class ImageConverter { 24.26 - 24.27 - static void convert(File source, File dest, String format, 24.28 - int maxWidth, int maxHeight) 24.29 - throws IOException, InterruptedException { 24.30 - 24.31 - System.err.print("Converting image " + source + "... "); 24.32 - 24.33 - if (source.lastModified() < dest.lastModified()) { 24.34 - System.err.println(dest + " is up to date."); 24.35 - return; 24.36 - } 24.37 - 24.38 - BufferedImage image = ImageIO.read(source); 24.39 - 24.40 - //int type = image.getType(); 24.41 - //final int type = BufferedImage.TYPE_INT_RGB; 24.42 - //ColorModel cm = image.getColorModel(); 24.43 - 24.44 - int w = image.getWidth(null); 24.45 - int h = image.getHeight(null); 24.46 - 24.47 - //boolean scale = false; 24.48 - 24.49 - float scale = 1f; 24.50 - 24.51 - if (maxWidth > 0 && w > maxWidth) 24.52 - scale = (float)maxWidth / w; 24.53 - 24.54 - if (maxHeight > 0 && h * scale > maxHeight) 24.55 - scale = (float)maxHeight / h; 24.56 - 24.57 - if (scale != 1f) { 24.58 - w *= scale; h *= scale; 24.59 - 24.60 -// ColorModel cm = image.getColorModel(); 24.61 -// boolean alphaPremultiplied = cm.isAlphaPremultiplied(); 24.62 -// WritableRaster raster = cm.createCompatibleWritableRaster(w, h); 24.63 -// BufferedImage scaled = new BufferedImage 24.64 -// (cm, raster, alphaPremultiplied, null); 24.65 - 24.66 -// BufferedImage scaled = new BufferedImage(w, h, image.getType()); 24.67 - 24.68 - 24.69 - Image scaled = image.getScaledInstance(w, h, Image.SCALE_SMOOTH); 24.70 - 24.71 - ColorModel cm = image.getColorModel(); 24.72 - boolean alphaPremultiplied = image.isAlphaPremultiplied(); 24.73 - WritableRaster raster = cm.createCompatibleWritableRaster(w, h); 24.74 - image = new BufferedImage(cm, raster, alphaPremultiplied, null); 24.75 - 24.76 - Graphics g = image.getGraphics(); 24.77 - g.drawImage(scaled, 0, 0, null); 24.78 - g.dispose(); 24.79 - 24.80 -// image = scale(image, scaled, scale); 24.81 -// Graphics2D g = scaled.createGraphics(); 24.82 -// g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, 24.83 -// RenderingHints.VALUE_INTERPOLATION_BILINEAR); 24.84 -// System.err.print(" " + g.drawImage(image, 0, 0, w, h, null) + " "); 24.85 -// g.dispose(); 24.86 -// image = scaled; 24.87 - } 24.88 - 24.89 - File parent = dest.getParentFile(); 24.90 - if (parent != null) parent.mkdirs(); 24.91 - 24.92 - ImageIO.write(image, format, dest); 24.93 - System.err.println("saved " + dest + "."); 24.94 - } 24.95 - 24.96 -// public static ColorModel getColorModel(Image image) 24.97 -// throws InterruptedException { 24.98 - 24.99 -// PixelGrabber grabby = new PixelGrabber(image, 0, 0, 1, 1, false); 24.100 -// if (!grabby.grabPixels()) 24.101 -// throw new RuntimeException("pixel grab fails"); 24.102 -// return grabby.getColorModel(); 24.103 -// } 24.104 - 24.105 -// private static BufferedImage scale(BufferedImage image, 24.106 -// BufferedImage dest, 24.107 -// float scale) { 24.108 - 24.109 -// AffineTransform tx = new AffineTransform(); 24.110 -// tx.scale(scale, scale); 24.111 - 24.112 -// AffineTransformOp op = new AffineTransformOp 24.113 -// (tx, AffineTransformOp.TYPE_BILINEAR); 24.114 - 24.115 -// return op.filter(image, dest); 24.116 -// } 24.117 - 24.118 - // TEST 24.119 - 24.120 - public static void main(String[] args) 24.121 - throws IOException, InterruptedException { 24.122 - 24.123 - convert(new File(args[0]), new File(args[1]), "png", 300, 300); 24.124 - } 24.125 - 24.126 - 24.127 -// public static BufferedImage toBufferedImage(Image image, ColorModel cm) { 24.128 -// if (image instanceof BufferedImage) 24.129 -// return (BufferedImage)image; 24.130 - 24.131 -// int w = image.getWidth(null); 24.132 -// int h = image.getHeight(null); 24.133 - 24.134 -// boolean alphaPremultiplied = cm.isAlphaPremultiplied(); 24.135 -// WritableRaster raster = cm.createCompatibleWritableRaster(w, h); 24.136 -// BufferedImage result = new BufferedImage(cm, raster, alphaPremultiplied, null); 24.137 -// Graphics2D g = result.createGraphics(); 24.138 - 24.139 -// g.drawImage(image, 0, 0, null); 24.140 -// g.dispose(); 24.141 - 24.142 -// return result; 24.143 -// } 24.144 -} 24.145 - 24.146 - 24.147 -// This is how I'd recommend it in JDK1.4 using javax.imageio.ImageIO to 24.148 -// do the reading/writing and Java2D to do the scaling. 24.149 - 24.150 -// // read in the original image 24.151 -// BufferedImage in = ImageIO.read(new File("in.jpg")); 24.152 - 24.153 -// // create a new image of the smaller size 24.154 -// BufferedImage out = new BufferedImage(newWidth, newHeight); 24.155 - 24.156 -// // get the graphics associated with the new image 24.157 -// Graphics g = out.getGraphics(); 24.158 - 24.159 -// // draw the original image into the new image, scaling 24.160 -// // on the fly 24.161 -// g.drawImage(in, newWidth, newHeight, null); 24.162 - 24.163 -// // dispose the graphics object 24.164 -// g.dispose(); 24.165 - 24.166 -// // write out the new image 24.167 -// ImagIO.write("out.jpg", "jpeg", new File("out.jpg")); 24.168 - 24.169 -// ------------------------------------------ 24.170 - 24.171 -// For nicer scaling, you could add a rendering hint to the graphics 24.172 -// object before painting. 24.173 - 24.174 -// ie. 24.175 - 24.176 -// Graphics2D g2d = (Graphics2D)g; 24.177 -// g2d.setRenderingHint(RenderingHints.KEY_INTEPOLATION, 24.178 -// RenderingHints.VALUE_INTERPOLATION_BILINEAR); 24.179 - 24.180 -// or use VALUE_INTERPOLATION_BICUBIC for the best. 24.181 - 24.182 -// But as you can guess, nicer == slower. 24.183 - 24.184 -// Shannon Hickey 24.185 -// shann...@swingteam.com 24.186 -// Swing Team http://TheSwingConnection.com http://TheJavaTutorial.com 24.187 -// Java Software, a division of Sun Microsystems, Inc.
25.1 --- a/src/kryshen/tema/ReplaceWriter.java Tue May 16 18:04:09 2006 +0400 25.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 25.3 @@ -1,140 +0,0 @@ 25.4 -/* 25.5 - * Copyright (C) 2006 Mikhail A. Kryshen 25.6 - * 25.7 - * $Id: ReplaceWriter.java,v 1.1.1.1 2006/05/16 14:04:09 mikhail Exp $ 25.8 - */ 25.9 - 25.10 -package kryshen.tema; 25.11 - 25.12 -import java.io.Writer; 25.13 -import java.io.FilterWriter; 25.14 -import java.io.IOException; 25.15 - 25.16 -import java.util.LinkedList; 25.17 -import java.util.Iterator; 25.18 - 25.19 -/** 25.20 - * FilterWriter which replaces characters with escape strings. 25.21 - * 25.22 - * @author Mikhail A. Kryshen 25.23 - */ 25.24 -class ReplaceWriter extends FilterWriter { 25.25 - private String[] patterns; 25.26 - private String[] replaces; 25.27 - 25.28 - private String prefix; 25.29 - private String postfix; 25.30 - 25.31 - private int maxPatternLength = 0; 25.32 - 25.33 - /** Had this Writer processed any data? */ 25.34 - private boolean processedData = false; 25.35 - 25.36 - private StringBuffer buffer = new StringBuffer(); 25.37 - 25.38 - public ReplaceWriter(Writer w, String pattern, String replace) { 25.39 - this(w, new String[]{pattern}, new String[]{replace}); 25.40 - } 25.41 - 25.42 - public ReplaceWriter(Writer w, String pattern, String replace, 25.43 - String prefix, String postfix) { 25.44 - 25.45 - this(w, new String[]{pattern}, new String[]{replace}, 25.46 - prefix, postfix); 25.47 - } 25.48 - 25.49 - public ReplaceWriter(Writer w, String[] patterns, String[] replaces) { 25.50 - this(w, patterns, replaces, null, null); 25.51 - } 25.52 - 25.53 - public ReplaceWriter(Writer w, String[] patterns, String[] replaces, 25.54 - String prefix, String postfix) { 25.55 - super(w); 25.56 - 25.57 - this.patterns = patterns; 25.58 - this.replaces = replaces; 25.59 - 25.60 - this.prefix = prefix; 25.61 - this.postfix = postfix; 25.62 - 25.63 - for (int i = 0; i < patterns.length; i++) { 25.64 - int length = patterns[i].length(); 25.65 - if (length > maxPatternLength) 25.66 - maxPatternLength = length; 25.67 - } 25.68 - } 25.69 - 25.70 - private boolean processBuffer(int minLength) throws IOException { 25.71 - if (buffer.length() == 0) return false; 25.72 - 25.73 - if (!processedData) { 25.74 - if (prefix != null) 25.75 - super.write(prefix, 0, prefix.length()); 25.76 - processedData = true; 25.77 - } 25.78 - 25.79 - int k; 25.80 - for (k = 0; minLength + k < buffer.length(); k++) { 25.81 - for (int i = 0; i < patterns.length; i++) { 25.82 - String pattern = patterns[i]; 25.83 - int length = pattern.length(); 25.84 - 25.85 - if (length + k > buffer.length()) 25.86 - continue; 25.87 - 25.88 - boolean match = true; 25.89 - 25.90 - for (int j = 0; j < length; j++) { 25.91 - if (pattern.charAt(j) != buffer.charAt(j + k)) { 25.92 - match = false; 25.93 - break; 25.94 - } 25.95 - } 25.96 - 25.97 - if (match) { 25.98 - super.write(buffer.substring(0, k), 0, k); 25.99 - buffer.delete(0, k + length); 25.100 - super.write(replaces[i], 0, replaces[i].length()); 25.101 - return true; 25.102 - } 25.103 - } 25.104 - } 25.105 - 25.106 - super.write(buffer.substring(0, k), 0, k); 25.107 - buffer.delete(0, k); 25.108 - 25.109 - return false; 25.110 - } 25.111 - 25.112 - public void write(int c) throws IOException { 25.113 - buffer.append((char)c); 25.114 - processBuffer(maxPatternLength); 25.115 - } 25.116 - 25.117 - public void write(char[] cbuf, int off, int len) throws IOException { 25.118 - for (int i = off; i < off + len; i++) { 25.119 - buffer.append(cbuf[i]); 25.120 - } 25.121 - processBuffer(maxPatternLength); 25.122 - } 25.123 - 25.124 - public void write(String str, int off, int len) throws IOException { 25.125 - buffer.append(str.substring(off, off + len)); 25.126 - processBuffer(maxPatternLength); 25.127 - } 25.128 - 25.129 - public void finish() throws IOException { 25.130 - while (processBuffer(0)); 25.131 - 25.132 -// super.write(buffer.toString(), 0, buffer.length()); 25.133 -// buffer.delete(0, buffer.length()); 25.134 - 25.135 - if (processedData && postfix != null) 25.136 - super.write(postfix, 0, postfix.length()); 25.137 - } 25.138 - 25.139 - public void close() throws IOException { 25.140 - finish(); 25.141 - super.close(); 25.142 - } 25.143 -}
26.1 --- a/src/kryshen/tema/Tema.java Tue May 16 18:04:09 2006 +0400 26.2 +++ b/src/kryshen/tema/Tema.java Thu Dec 14 23:22:05 2006 +0300 26.3 @@ -1,7 +1,21 @@ 26.4 /* 26.5 - * Copyright (C) 2005, 2006 Mikhail A. Kryshen 26.6 + * Copyright (C) 2005, 2006 Mikhail A. Kryshen 26.7 * 26.8 - * $Id: Tema.java,v 1.1.1.1 2006/05/16 14:04:09 mikhail Exp $ 26.9 + * This program is free software; you can redistribute it and/or modify 26.10 + * it under the terms of the GNU General Public License as published by 26.11 + * the Free Software Foundation; either version 2 of the License, or 26.12 + * (at your option) any later version. 26.13 + * 26.14 + * This program is distributed in the hope that it will be useful, 26.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 26.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 26.17 + * GNU General Public License for more details. 26.18 + * 26.19 + * You should have received a copy of the GNU General Public License 26.20 + * along with this program; if not, write to the Free Software 26.21 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 26.22 + * 26.23 + * $Id: Tema.java,v 1.17 2006/12/14 19:44:31 mikhail Exp $ 26.24 */ 26.25 26.26 package kryshen.tema; 26.27 @@ -23,31 +37,135 @@ 26.28 26.29 import java.io.*; 26.30 26.31 +import kryshen.tema.demo.DemoFrame; 26.32 + 26.33 /** 26.34 * Tema main class. 26.35 * 26.36 * @author Mikhail A. Kryshen 26.37 */ 26.38 public class Tema { 26.39 + public static final String TITLE = "TEMA"; 26.40 + public static final String VERSION = "0.1"; 26.41 + public static final String AUTHOR = "Mikhail A. Kryshen"; 26.42 + 26.43 private static final String CONFIG_FILE = "tema.properties"; 26.44 private static final String ENV_PREFIX = "kryshen.tema."; 26.45 26.46 private static Properties config = new Properties(); 26.47 - static Connection connection = null; 26.48 + private static Connection connection = null; 26.49 26.50 private static String inputEncoding; 26.51 private static String outputEncoding; 26.52 26.53 - static Map<File, String> fileCache = null; 26.54 + private static Map<File, String> fileCache = null; 26.55 26.56 public static void main(String[] args) 26.57 - throws IOException, TemplateException, SQLException, 26.58 + throws IOException, SQLException, 26.59 ClassNotFoundException, InstantiationException, 26.60 IllegalAccessException { 26.61 26.62 + boolean demo = false; 26.63 + boolean version = false; 26.64 + boolean help = false; 26.65 + 26.66 + // Parse arguments. 26.67 + for (int i = 0; i < args.length; i++) { 26.68 + if ("-demo".equals(args[i]) || 26.69 + "-d".equals(args[i])) { 26.70 + demo = true; 26.71 + } else if ("-version".equals(args[i]) || 26.72 + "-v".equals(args[i])) { 26.73 + version = true; 26.74 + } else if ("-help".equals(args[i]) || 26.75 + "-h".equals(args[i]) || 26.76 + "-usage".equals(args[i]) || 26.77 + "-u".equals(args[i])) { 26.78 + help = true; 26.79 + } else { 26.80 + System.err.println("Invalid option: " + args[i]); 26.81 + return; 26.82 + } 26.83 + } 26.84 + 26.85 + if (version || help) { 26.86 + System.err.println(TITLE + " " + VERSION + " by " + AUTHOR); 26.87 + 26.88 + if (help) { 26.89 + PrintStream err = System.err; 26.90 + 26.91 + err.println(); 26.92 + err.println("Usage: tema [OPTIONS]"); 26.93 + err.println(); 26.94 + err.println("Options:"); 26.95 + err.println(" -d[emo] Demo mode"); 26.96 + err.println(" -v[ersion] Print version"); 26.97 + err.println(" -h[help] -u[sage] Print this help message"); 26.98 + } 26.99 + return; 26.100 + } 26.101 + 26.102 + if (demo) { 26.103 + // Run in demo mode. 26.104 + DemoFrame df = new DemoFrame(); 26.105 + df.pack(); 26.106 + df.setVisible(true); 26.107 + return; 26.108 + } 26.109 + 26.110 + process(); 26.111 + } 26.112 + 26.113 + /** 26.114 + * Standard execution. 26.115 + */ 26.116 + private static void process() 26.117 + throws IOException, SQLException, 26.118 + ClassNotFoundException, InstantiationException, 26.119 + IllegalAccessException { 26.120 + 26.121 InputStream configIn = new FileInputStream(CONFIG_FILE); 26.122 config.load(configIn); 26.123 configIn.close(); 26.124 + 26.125 + configure(); 26.126 + 26.127 + String main = getProperty("main_template"); 26.128 + String output = getProperty("output"); 26.129 + 26.130 + Writer out; 26.131 + 26.132 + if ("stderr".equals(output)) 26.133 + out = new OutputStreamWriter(System.err); 26.134 + else 26.135 + out = new OutputStreamWriter(System.out); 26.136 + 26.137 + TemplateReader in = createTemplateReader(new File(main)); 26.138 + TemplateParser p = new TemplateParser(); 26.139 + TemplateException te = null; 26.140 + 26.141 + try { 26.142 + p.parse(in, out); 26.143 + } catch (TemplateException e) { 26.144 + te = e; 26.145 + } finally { 26.146 + in.close(); 26.147 + out.flush(); 26.148 + } 26.149 + 26.150 + if (te != null) { 26.151 + System.err.println(te.getMessage()); 26.152 + if (te.getCause() != null) { 26.153 + System.err.println("Caused by " + te.getCause()); 26.154 + } 26.155 + } else { 26.156 + System.err.println("Done"); 26.157 + } 26.158 + } 26.159 + 26.160 + private static void configure() 26.161 + throws IOException, SQLException, IllegalAccessException, 26.162 + ClassNotFoundException, InstantiationException { 26.163 26.164 String logFile = getProperty("log"); 26.165 if (logFile != null && logFile.length() > 0) 26.166 @@ -71,51 +189,14 @@ 26.167 // Open connection. 26.168 connection = DriverManager.getConnection(resourceProperty); 26.169 } 26.170 - 26.171 -// String maxFilesString = getProperty("max_output_files"); 26.172 -// int maxFiles = -1; 26.173 -// if (maxFilesString != null) 26.174 -// maxFiles = Integer.parseInt(maxFilesString); 26.175 - 26.176 - String main = getProperty("main_template"); 26.177 - String output = getProperty("output"); 26.178 - 26.179 - Writer out; 26.180 - 26.181 - if ("stderr".equals(output)) 26.182 - out = new OutputStreamWriter(System.err); 26.183 - else 26.184 - out = new OutputStreamWriter(System.out); 26.185 - 26.186 - InputStream is = new FileInputStream(main); 26.187 - Reader in = new BufferedReader(new InputStreamReader(is, inputEncoding)); 26.188 - 26.189 - TemplateParser p = new TemplateParser(); 26.190 - try { 26.191 - p.parse(in, out); 26.192 - } finally { 26.193 - in.close(); 26.194 - out.flush(); 26.195 - } 26.196 - 26.197 - System.err.println("Done"); 26.198 } 26.199 26.200 -// private static void readEscapes() { 26.201 -// for (int i = 1;; i++) { 26.202 -// String pattern = getProperty("escape_char_" + i); 26.203 - 26.204 -// if (pattern == null) break; 26.205 - 26.206 -// escapes.put(pattern.charAt(0), 26.207 -// getProperty("escape_string_" + i)); 26.208 -// } 26.209 -// } 26.210 + 26.211 26.212 /** 26.213 * Get configuration property. 26.214 */ 26.215 - static String getProperty(String name) { 26.216 + public static String getProperty(String name) { 26.217 String value = System.getProperty(ENV_PREFIX + name); 26.218 if (value != null) return value; 26.219 return config.getProperty(name); 26.220 @@ -124,16 +205,17 @@ 26.221 /** 26.222 * Get configuration property. 26.223 */ 26.224 - static String getProperty(String name, String fallback) { 26.225 + public static String getProperty(String name, String fallback) { 26.226 String value = getProperty(name); 26.227 if (value != null) return value; 26.228 return fallback; 26.229 } 26.230 26.231 /** 26.232 - * Process subquery and template. 26.233 + * Process database query. 26.234 * 26.235 - * @param template template to fill with data. 26.236 + * @param templateReader reader for the template 26.237 + * to fill with data. 26.238 * @param ps query statement to execute. 26.239 * @param args list of query parameters. 26.240 * @param superParser invoking object. 26.241 @@ -141,14 +223,13 @@ 26.242 * 26.243 * @return number of processed rows in query result. 26.244 */ 26.245 - static int query(String template, PreparedStatement ps, 26.246 - List<String> args, 26.247 - TemplateParser superParser, 26.248 - Writer out) 26.249 + public static int query(TemplateReader templateReader, 26.250 + PreparedStatement ps, 26.251 + List<String> args, 26.252 + TemplateParser superParser, 26.253 + Writer out) 26.254 throws IOException, SQLException, TemplateException { 26.255 26.256 - StringReader templateReader = new StringReader(template); 26.257 - 26.258 int i = 1; 26.259 26.260 for (String arg : args) { 26.261 @@ -165,21 +246,34 @@ 26.262 names[j] = rm.getColumnName(j + 1); 26.263 } 26.264 26.265 - TemplateParser p = new TemplateParser(superParser); 26.266 - 26.267 + final TemplateParser p = new TemplateParser(superParser); 26.268 + final HashMap<String, Object> fields = new HashMap<String, Object>(); 26.269 + 26.270 + p.registerFunction("db", new Function() { 26.271 + public int invoke(FunctionDataParser fdp, 26.272 + final Writer out) 26.273 + throws IOException, TemplateException { 26.274 + 26.275 + String name = fdp.getData(); 26.276 + Object value = fields.get(name); 26.277 + 26.278 + return p.parseValue(value, out); 26.279 + } 26.280 + }); 26.281 + 26.282 for (i = 1; r.next(); i++) { 26.283 - p.clearValues(); 26.284 26.285 for (int j = 0; j < columnCount; j++) { 26.286 Object value = r.getObject(j + 1); 26.287 if (r.wasNull()) value = null; 26.288 - 26.289 - p.setValue(names[j], value); 26.290 + 26.291 + fields.put(names[j], value); 26.292 } 26.293 26.294 - p.setValue("NUMBER", i); 26.295 + p.setValue("number", i); 26.296 p.parse(templateReader, out); 26.297 templateReader.reset(); 26.298 + fields.clear(); 26.299 } 26.300 26.301 r.close(); 26.302 @@ -187,32 +281,56 @@ 26.303 return i - 1; 26.304 } 26.305 26.306 - static Writer createFileWriter(String filename) throws IOException { 26.307 + public static BufferedWriter createFileWriter(String filename) 26.308 + throws IOException { 26.309 + 26.310 OutputStream os = new FileOutputStream(filename); 26.311 - return new OutputStreamWriter(os, Tema.outputEncoding); 26.312 + return new BufferedWriter 26.313 + (new OutputStreamWriter(os, Tema.outputEncoding)); 26.314 } 26.315 26.316 - static Reader createFileReader(File file) throws IOException { 26.317 + public static BufferedReader createFileReader(File file) 26.318 + throws IOException { 26.319 + 26.320 InputStream is = new FileInputStream(file); 26.321 - return new InputStreamReader(is, Tema.inputEncoding); 26.322 + return new BufferedReader 26.323 + (new InputStreamReader(is, Tema.inputEncoding)); 26.324 } 26.325 26.326 - static Reader createCachedFileReader(File file) throws IOException { 26.327 + public static TemplateReader createTemplateReader(File file) 26.328 + throws IOException { 26.329 + 26.330 + return new TemplateReader 26.331 + (new LineNumberReader(createCachedFileReader(file)), file.getPath()); 26.332 + } 26.333 + 26.334 + /** 26.335 + * Creates StringReader for a cached file if caching is enabled or 26.336 + * a BufferedReader. 26.337 + * 26.338 + * @param file File to read. 26.339 + * @return Reader for a file. 26.340 + */ 26.341 + public static Reader createCachedFileReader(File file) 26.342 + throws IOException { 26.343 + 26.344 if (fileCache != null) return new StringReader(readFile(file)); 26.345 else return createFileReader(file); 26.346 } 26.347 26.348 /** 26.349 * Read text file. 26.350 + * 26.351 + * @return file contents. 26.352 */ 26.353 - static String readFile(File file) throws IOException { 26.354 + public static String readFile(File file) throws IOException { 26.355 String data; 26.356 - 26.357 + 26.358 if (fileCache != null) { 26.359 data = fileCache.get(file); 26.360 if (data != null) return data; 26.361 } 26.362 - 26.363 + 26.364 Reader r = new BufferedReader(createFileReader(file)); 26.365 26.366 // FIXME: possible overflow (long -> int). 26.367 @@ -234,4 +352,13 @@ 26.368 26.369 return data; 26.370 } 26.371 + 26.372 + /** 26.373 + * Get database connection. 26.374 + * 26.375 + * @return database connection if any was configured. 26.376 + */ 26.377 + public static Connection getDbConnection() { 26.378 + return connection; 26.379 + } 26.380 }
27.1 --- a/src/kryshen/tema/TemplateException.java Tue May 16 18:04:09 2006 +0400 27.2 +++ b/src/kryshen/tema/TemplateException.java Thu Dec 14 23:22:05 2006 +0300 27.3 @@ -1,7 +1,21 @@ 27.4 /* 27.5 - * Copyright (C) 2006 Mikhail A. Kryshen 27.6 + * Copyright (C) 2006 Mikhail A. Kryshen 27.7 * 27.8 - * $Id: TemplateException.java,v 1.1.1.1 2006/05/16 14:04:09 mikhail Exp $ 27.9 + * This program is free software; you can redistribute it and/or modify 27.10 + * it under the terms of the GNU General Public License as published by 27.11 + * the Free Software Foundation; either version 2 of the License, or 27.12 + * (at your option) any later version. 27.13 + * 27.14 + * This program is distributed in the hope that it will be useful, 27.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 27.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 27.17 + * GNU General Public License for more details. 27.18 + * 27.19 + * You should have received a copy of the GNU General Public License 27.20 + * along with this program; if not, write to the Free Software 27.21 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 27.22 + * 27.23 + * $Id: TemplateException.java,v 1.5 2006/12/14 14:39:22 mikhail Exp $ 27.24 */ 27.25 27.26 package kryshen.tema; 27.27 @@ -12,13 +26,36 @@ 27.28 * @author Mikhail A. Kryshen 27.29 */ 27.30 public class TemplateException extends Exception { 27.31 - // TODO: store the number of template line with error. 27.32 + //private String source; 27.33 + //private int line; 27.34 27.35 - public TemplateException(String message) { 27.36 - super(message); 27.37 +// public TemplateException(String message) { 27.38 +// super(message); 27.39 +// } 27.40 + 27.41 +// public TemplateException(String message, Throwable cause) { 27.42 +// super(message, cause); 27.43 +// } 27.44 + 27.45 + public TemplateException(String message, Throwable cause, 27.46 + TemplateReader tr) { 27.47 + this(message, cause, tr.getSource(), tr.getLineNumber() + 1); 27.48 } 27.49 27.50 - public TemplateException(String message, Throwable cause) { 27.51 - super(message, cause); 27.52 + public TemplateException(String message, TemplateReader tr) { 27.53 + this(message, tr.getSource(), tr.getLineNumber() + 1); 27.54 + } 27.55 + 27.56 + public TemplateException(String message, Throwable cause, 27.57 + String source, int line) { 27.58 + super(source + ":" + line + ": " + message, cause); 27.59 + //this.source = source; 27.60 + //this.line = line; 27.61 + } 27.62 + 27.63 + public TemplateException(String message, String source, int line) { 27.64 + super(source + ":" + line + ": " + message); 27.65 + //this.source = source; 27.66 + //this.line = line; 27.67 } 27.68 }
28.1 --- a/src/kryshen/tema/TemplateParser.java Tue May 16 18:04:09 2006 +0400 28.2 +++ b/src/kryshen/tema/TemplateParser.java Thu Dec 14 23:22:05 2006 +0300 28.3 @@ -1,7 +1,21 @@ 28.4 /* 28.5 - * Copyright (C) 2005, 2006 Mikhail A. Kryshen 28.6 + * Copyright (C) 2005, 2006 Mikhail A. Kryshen 28.7 * 28.8 - * $Id: TemplateParser.java,v 1.1.1.1 2006/05/16 14:04:09 mikhail Exp $ 28.9 + * This program is free software; you can redistribute it and/or modify 28.10 + * it under the terms of the GNU General Public License as published by 28.11 + * the Free Software Foundation; either version 2 of the License, or 28.12 + * (at your option) any later version. 28.13 + * 28.14 + * This program is distributed in the hope that it will be useful, 28.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 28.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28.17 + * GNU General Public License for more details. 28.18 + * 28.19 + * You should have received a copy of the GNU General Public License 28.20 + * along with this program; if not, write to the Free Software 28.21 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 28.22 + * 28.23 + * $Id: TemplateParser.java,v 1.11 2006/12/14 19:44:31 mikhail Exp $ 28.24 */ 28.25 28.26 package kryshen.tema; 28.27 @@ -10,12 +24,14 @@ 28.28 import java.util.*; 28.29 28.30 /** 28.31 - * Parser for DbReader templates. 28.32 + * Parser for TEMA templates. 28.33 * 28.34 * @author Mikhail A. Kryshen 28.35 */ 28.36 public class TemplateParser { 28.37 - static final String SUPER = "SUPER."; 28.38 + // TODO: report non-critical errors and warnings. 28.39 + 28.40 + static final String SUPER_PREFIX = "super."; 28.41 28.42 /* Brackets. */ 28.43 static final char[] BR_LEFT = {'<', '['}; 28.44 @@ -28,6 +44,9 @@ 28.45 static final char[] NONREC_DATA_SEPARATORS = {'\\', '`'}; 28.46 static final char[] LIST_SEPARATORS = {' ', '\t', '\r', '\n'}; 28.47 28.48 + /** 28.49 + * Methods of parsing function arguments and data. 28.50 + */ 28.51 static enum FunctionData { 28.52 SUBFUNCTION, RECURSIVE, NONRECURSIVE; 28.53 }; 28.54 @@ -38,24 +57,22 @@ 28.55 28.56 static class Result { 28.57 Terminator terminator; 28.58 - int substitutions; 28.59 + int retCode; 28.60 28.61 /** No text had been parsed. */ 28.62 boolean empty; 28.63 28.64 - Result(Terminator terminator, int substitutions, boolean empty) { 28.65 + Result(Terminator terminator, int retCode, boolean empty) { 28.66 this.terminator = terminator; 28.67 - this.substitutions = substitutions; 28.68 + this.retCode = retCode; 28.69 this.empty = empty; 28.70 } 28.71 28.72 Result() { 28.73 - this(null, 0, true); 28.74 + this(null, -1, true); 28.75 } 28.76 }; 28.77 28.78 - private Map<String, Function> functions = new HashMap<String, Function>(); 28.79 - 28.80 private Map<String, Object> variables = new HashMap<String, Object>(); 28.81 private TemplateParser superParser; 28.82 28.83 @@ -71,26 +88,26 @@ 28.84 Functions.registerAllFunctions(this); 28.85 } 28.86 28.87 - public void registerFunction(Function f) { 28.88 - functions.put(f.name, f); 28.89 + public void registerFunction(String name, Function f) { 28.90 + variables.put(name, f); 28.91 } 28.92 28.93 - public int parse(Reader in, Writer out) 28.94 + public int parse(TemplateReader in, Writer out) 28.95 throws IOException, TemplateException { 28.96 28.97 - return parse(in, out, true, null, null).substitutions; 28.98 + return parse(in, out, true, null, null).retCode; 28.99 } 28.100 28.101 /** 28.102 * Parse template. 28.103 * 28.104 - * @param in Reader to read template data. 28.105 + * @param in TemplateReader to read template data. 28.106 * @param out Writer to write processed data. 28.107 * @param recursive enables recursive processing. 28.108 * @param separators characters which terminate parsing block. 28.109 * @param leading characters to ignore at the beginning of the block. 28.110 */ 28.111 - Result parse(Reader in, Writer out, boolean recursive, 28.112 + Result parse(TemplateReader in, Writer out, boolean recursive, 28.113 char[] separators, char[] leading) 28.114 throws IOException, TemplateException { 28.115 28.116 @@ -117,10 +134,13 @@ 28.117 28.118 if (recursive && leftBracket && c == BR_IN) { 28.119 28.120 + if (result.retCode < 0) 28.121 + result.retCode = 0; 28.122 + 28.123 lc = -1; 28.124 int tb = termBracket; 28.125 termBracket = BR_RIGHT[index]; 28.126 - result.substitutions += parseFunction(in, out); 28.127 + result.retCode += parseFunction(in, out); 28.128 termBracket = tb; 28.129 28.130 } else if (lc == BR_IN && c == termBracket) { 28.131 @@ -151,22 +171,6 @@ 28.132 return result; 28.133 } 28.134 28.135 - int parseVariable(String name, Writer out) 28.136 - throws IOException, TemplateException { 28.137 - 28.138 - Object ovalue = getValue(name); 28.139 - if (ovalue == null) 28.140 - return 0; 28.141 - 28.142 - String svalue = ovalue.toString(); 28.143 - 28.144 - if (svalue == null || svalue.length() == 0) 28.145 - return 0; 28.146 - 28.147 - out.write(svalue); 28.148 - return 1; 28.149 - } 28.150 - 28.151 boolean isSeparator(int c, char[] separators) { 28.152 for (char p : separators) { 28.153 if (c == p) return true; 28.154 @@ -175,7 +179,7 @@ 28.155 return false; 28.156 } 28.157 28.158 - int parseFunction(Reader in, Writer out) 28.159 + int parseFunction(TemplateReader in, Writer out) 28.160 throws IOException, TemplateException { 28.161 28.162 StringBuffer sb = new StringBuffer(); 28.163 @@ -196,16 +200,28 @@ 28.164 FunctionData.NONRECURSIVE, 28.165 in, out); 28.166 } else if (c < 0) { 28.167 - System.err.println("Error: unexpected end of file."); 28.168 - return 0; 28.169 + throw new TemplateException("Unexpected end of file.", in); 28.170 } else { 28.171 sb.append((char)c); 28.172 } 28.173 } 28.174 } 28.175 28.176 + int parseValue(Object value, Writer out) throws IOException { 28.177 + if (value == null) 28.178 + return 0; 28.179 + 28.180 + String svalue = value.toString(); 28.181 + 28.182 + if (svalue == null || svalue.length() == 0) 28.183 + return 0; 28.184 + 28.185 + out.write(svalue); 28.186 + return 1; 28.187 + } 28.188 + 28.189 private int invokeFunction(String name, FunctionData fd, 28.190 - Reader in, Writer out) 28.191 + TemplateReader in, Writer out) 28.192 throws IOException, TemplateException { 28.193 28.194 FunctionDataParser fdp = new FunctionDataParser(this, fd, in); 28.195 @@ -214,14 +230,15 @@ 28.196 return fdp.parseData(out); 28.197 } 28.198 28.199 - Function f = getFunction(name); 28.200 + Object value = getValue(name); 28.201 + int r; 28.202 28.203 - if (f == null) { 28.204 - throw new TemplateException("Unknown function: " + name); 28.205 + if (value instanceof Function) { 28.206 + r = ((Function) value).invoke(fdp, out); 28.207 + } else { 28.208 + r = parseValue(value, out); 28.209 } 28.210 28.211 - int r = f.invoke(fdp, out); 28.212 - 28.213 if (fdp.hasMoreData()) { 28.214 /* Skip remaining function data. */ 28.215 fdp.parseData(new Writer() { 28.216 @@ -234,27 +251,14 @@ 28.217 return r; 28.218 } 28.219 28.220 - Function getFunction(String name) throws TemplateException { 28.221 - Function function = functions.get(name); 28.222 - if (function != null) return function; 28.223 - 28.224 - if (superParser != null) { 28.225 - if (name.startsWith(SUPER)) 28.226 - return superParser.getFunction(name.substring(SUPER.length())); 28.227 - else 28.228 - return superParser.getFunction(name); 28.229 - } 28.230 - 28.231 - return null; 28.232 - } 28.233 - 28.234 - Object getValue(String name) throws TemplateException { 28.235 + public Object getValue(String name) throws TemplateException { 28.236 Object value = variables.get(name); 28.237 if (value != null) return value; 28.238 28.239 if (superParser != null) { 28.240 - if (name.startsWith(SUPER)) 28.241 - return superParser.getValue(name.substring(SUPER.length())); 28.242 + if (name.startsWith(SUPER_PREFIX)) 28.243 + return superParser.getValue 28.244 + (name.substring(SUPER_PREFIX.length())); 28.245 else 28.246 return superParser.getValue(name); 28.247 } 28.248 @@ -262,21 +266,26 @@ 28.249 return null; 28.250 } 28.251 28.252 - void setValue(String name, Object value) { 28.253 + public void setValue(String name, Object value) { 28.254 variables.put(name, value); 28.255 } 28.256 28.257 - void clearValues() { 28.258 + public void clearValues() { 28.259 variables.clear(); 28.260 + Functions.registerAllFunctions(this); 28.261 } 28.262 28.263 // TEST 28.264 - public static void main(String[] args) 28.265 + public static void main(String[] args) 28.266 throws IOException, TemplateException { 28.267 28.268 TemplateParser p = new TemplateParser(); 28.269 28.270 - FileReader in = new FileReader("parser.in"); 28.271 + TemplateReader in = 28.272 + new TemplateReader 28.273 + (new LineNumberReader 28.274 + (new FileReader("parser.in")), "parser.in"); 28.275 + 28.276 FileWriter out = new FileWriter("parser.out"); 28.277 28.278 p.parse(in, out);
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/src/kryshen/tema/TemplateReader.java Thu Dec 14 23:22:05 2006 +0300 29.3 @@ -0,0 +1,64 @@ 29.4 +/* 29.5 + * Copyright (C) 2006 Mikhail A. Kryshen 29.6 + * 29.7 + * This program is free software; you can redistribute it and/or modify 29.8 + * it under the terms of the GNU General Public License as published by 29.9 + * the Free Software Foundation; either version 2 of the License, or 29.10 + * (at your option) any later version. 29.11 + * 29.12 + * This program is distributed in the hope that it will be useful, 29.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 29.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 29.15 + * GNU General Public License for more details. 29.16 + * 29.17 + * You should have received a copy of the GNU General Public License 29.18 + * along with this program; if not, write to the Free Software 29.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 29.20 + * 29.21 + * $Id: TemplateReader.java,v 1.5 2006/12/14 14:39:22 mikhail Exp $ 29.22 + */ 29.23 + 29.24 +package kryshen.tema; 29.25 + 29.26 +import java.io.Reader; 29.27 +import java.io.LineNumberReader; 29.28 +import java.io.FilterReader; 29.29 +import java.io.IOException; 29.30 + 29.31 +/** 29.32 + * Reader for TEMA templates. Stores data source name (commonly 29.33 + * filename) and tracks line numbers for error reporting. 29.34 + * 29.35 + * @author Mikhail A. Kryshen 29.36 + */ 29.37 +public class TemplateReader extends FilterReader { 29.38 + private String source = null; 29.39 + 29.40 + private LineNumberReader lnReader = null; 29.41 + private TemplateReader parentReader = null; 29.42 + 29.43 + public TemplateReader(LineNumberReader in, String source) { 29.44 + super(in); 29.45 + this.lnReader = in; 29.46 + this.source = source; 29.47 + } 29.48 + 29.49 + public TemplateReader(Reader in, TemplateReader parent) { 29.50 + super(in); 29.51 + this.source = source; 29.52 + } 29.53 + 29.54 + public String getSource() { 29.55 + if (source != null) 29.56 + return source; 29.57 + 29.58 + return parentReader.getSource(); 29.59 + } 29.60 + 29.61 + public int getLineNumber() { 29.62 + if (lnReader != null) 29.63 + return lnReader.getLineNumber(); 29.64 + 29.65 + return parentReader.getLineNumber(); 29.66 + } 29.67 +}
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 30.2 +++ b/src/kryshen/tema/demo/DemoFrame.java Thu Dec 14 23:22:05 2006 +0300 30.3 @@ -0,0 +1,181 @@ 30.4 +/* 30.5 + * Copyright (C) 2006 Mikhail A. Kryshen 30.6 + * 30.7 + * This program is free software; you can redistribute it and/or modify 30.8 + * it under the terms of the GNU General Public License as published by 30.9 + * the Free Software Foundation; either version 2 of the License, or 30.10 + * (at your option) any later version. 30.11 + * 30.12 + * This program is distributed in the hope that it will be useful, 30.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 30.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 30.15 + * GNU General Public License for more details. 30.16 + * 30.17 + * You should have received a copy of the GNU General Public License 30.18 + * along with this program; if not, write to the Free Software 30.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 30.20 + * 30.21 + * $Id: DemoFrame.java,v 1.3 2006/12/14 15:59:48 mikhail Exp $ 30.22 + */ 30.23 + 30.24 +package kryshen.tema.demo; 30.25 + 30.26 +import java.awt.*; 30.27 +import java.awt.event.*; 30.28 +import java.io.*; 30.29 +import java.net.URL; 30.30 + 30.31 +import kryshen.tema.*; 30.32 + 30.33 +/** 30.34 + * TEMA demonstation console. 30.35 + */ 30.36 +public class DemoFrame extends Frame { 30.37 + private TextArea input; 30.38 + private TextArea output; 30.39 + private TextArea error; 30.40 + 30.41 + public DemoFrame() { 30.42 + super("TEMA demo console"); 30.43 + 30.44 + GridBagLayout gbl = new GridBagLayout(); 30.45 + 30.46 + GridBagConstraints c = new GridBagConstraints(); 30.47 + 30.48 + setLayout(gbl); 30.49 + 30.50 + input = new TextArea(25, 40); 30.51 + input.setEditable(true); 30.52 + 30.53 + output = new TextArea(25, 40); 30.54 + output.setEditable(false); 30.55 + 30.56 + error = new TextArea(5, 80); 30.57 + error.setEditable(false); 30.58 + 30.59 + Label l; 30.60 + 30.61 + c.insets = new Insets(3, 3, 3, 3); 30.62 + c.fill = GridBagConstraints.BOTH; 30.63 + c.gridwidth = GridBagConstraints.RELATIVE; 30.64 + 30.65 + l = new Label("Enter your code and click \"Process\"."); 30.66 + 30.67 + gbl.setConstraints(l, c); 30.68 + add(l); 30.69 + 30.70 + Panel buttons = new Panel(); 30.71 + buttons.setLayout(new FlowLayout(FlowLayout.LEFT)); 30.72 + 30.73 + Button process = new Button("Process"); 30.74 + Button clear = new Button("Clear"); 30.75 + Button close = new Button("Close"); 30.76 + 30.77 + buttons.add(process); 30.78 + buttons.add(clear); 30.79 + buttons.add(close); 30.80 + 30.81 + c.gridwidth = GridBagConstraints.REMAINDER; 30.82 + 30.83 + gbl.setConstraints(buttons, c); 30.84 + add(buttons); 30.85 + 30.86 + c.fill = GridBagConstraints.BOTH; 30.87 + c.anchor = GridBagConstraints.CENTER; 30.88 + c.gridwidth = GridBagConstraints.RELATIVE; 30.89 + 30.90 + l = new Label("Input:"); 30.91 + 30.92 + gbl.setConstraints(l, c); 30.93 + add(l); 30.94 + 30.95 + c.gridwidth = GridBagConstraints.REMAINDER; 30.96 + 30.97 + l = new Label("Output:"); 30.98 + 30.99 + gbl.setConstraints(l, c); 30.100 + add(l); 30.101 + 30.102 + c.gridwidth = GridBagConstraints.RELATIVE; 30.103 + 30.104 + gbl.setConstraints(input, c); 30.105 + add(input); 30.106 + 30.107 + c.gridwidth = GridBagConstraints.REMAINDER; 30.108 + 30.109 + gbl.setConstraints(output, c); 30.110 + add(output); 30.111 + 30.112 + l = new Label("Errors:"); 30.113 + 30.114 + gbl.setConstraints(l, c); 30.115 + add(l); 30.116 + 30.117 + gbl.setConstraints(error, c); 30.118 + add(error); 30.119 + 30.120 + process.addActionListener(new ActionListener() { 30.121 + public void actionPerformed(ActionEvent e) { 30.122 + process(); 30.123 + } 30.124 + }); 30.125 + 30.126 + clear.addActionListener(new ActionListener() { 30.127 + public void actionPerformed(ActionEvent e) { 30.128 + error.setText(""); 30.129 + output.setText(""); 30.130 + input.setText(""); 30.131 + 30.132 + } 30.133 + }); 30.134 + 30.135 + close.addActionListener(new ActionListener() { 30.136 + public void actionPerformed(ActionEvent e) { 30.137 + dispose(); 30.138 + } 30.139 + }); 30.140 + 30.141 + addWindowListener(new WindowAdapter() { 30.142 + public void windowClosing(WindowEvent e) { 30.143 + dispose(); 30.144 + } 30.145 + }); 30.146 + 30.147 + URL source = getClass().getResource("demo.template"); 30.148 + StringBuffer buffer = new StringBuffer(); 30.149 + 30.150 + try { 30.151 + Reader in = new BufferedReader 30.152 + (new InputStreamReader(source.openStream(), "UTF-8")); 30.153 + 30.154 + for (int ch = in.read(); ch >= 0; ch = in.read()) { 30.155 + buffer.append((char)ch); 30.156 + } 30.157 + 30.158 + in.close(); 30.159 + } catch (IOException e) { 30.160 + e.printStackTrace(); 30.161 + } 30.162 + 30.163 + input.setText(buffer.toString()); 30.164 + } 30.165 + 30.166 + private void process() { 30.167 + String s = input.getText(); 30.168 + 30.169 + TemplateReader tr = new TemplateReader 30.170 + (new LineNumberReader(new StringReader(s)), "input"); 30.171 + TemplateParser tp = new TemplateParser(); 30.172 + StringWriter sw = new StringWriter(); 30.173 + 30.174 + error.setText(""); 30.175 + 30.176 + try { 30.177 + tp.parse(tr, sw); 30.178 + } catch (Exception e) { 30.179 + error.setText(e.toString()); 30.180 + } 30.181 + 30.182 + output.setText(sw.toString()); 30.183 + } 30.184 +}
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 31.2 +++ b/src/kryshen/tema/demo/Hello.java Thu Dec 14 23:22:05 2006 +0300 31.3 @@ -0,0 +1,43 @@ 31.4 +/* 31.5 + * Copyright (C) 2006 Mikhail A. Kryshen 31.6 + * 31.7 + * This program is free software; you can redistribute it and/or modify 31.8 + * it under the terms of the GNU General Public License as published by 31.9 + * the Free Software Foundation; either version 2 of the License, or 31.10 + * (at your option) any later version. 31.11 + * 31.12 + * This program is distributed in the hope that it will be useful, 31.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 31.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 31.15 + * GNU General Public License for more details. 31.16 + * 31.17 + * You should have received a copy of the GNU General Public License 31.18 + * along with this program; if not, write to the Free Software 31.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 31.20 + * 31.21 + * $Id: Hello.java,v 1.2 2006/12/14 14:39:24 mikhail Exp $ 31.22 + */ 31.23 + 31.24 +package kryshen.tema.demo; 31.25 + 31.26 +import java.io.Writer; 31.27 +import java.io.IOException; 31.28 +import kryshen.tema.*; 31.29 + 31.30 +/** 31.31 + * Example function implementation. 31.32 + * 31.33 + * @author Mikhail A. Kryshen 31.34 + */ 31.35 +public class Hello extends Function { 31.36 + public Hello() {} 31.37 + 31.38 + public int invoke(FunctionDataParser fdp, Writer out) 31.39 + throws IOException, TemplateException { 31.40 + 31.41 + out.write("Hello, "); 31.42 + fdp.parseData(out); 31.43 + 31.44 + return 1; 31.45 + } 31.46 +}
32.1 --- a/src/kryshen/tema/functions/Define.java Tue May 16 18:04:09 2006 +0400 32.2 +++ b/src/kryshen/tema/functions/Define.java Thu Dec 14 23:22:05 2006 +0300 32.3 @@ -1,7 +1,21 @@ 32.4 /* 32.5 - * Copyright (C) 2006 Mikhail A. Kryshen 32.6 + * Copyright (C) 2006 Mikhail A. Kryshen 32.7 * 32.8 - * $Id: Define.java,v 1.1.1.1 2006/05/16 14:04:09 mikhail Exp $ 32.9 + * This program is free software; you can redistribute it and/or modify 32.10 + * it under the terms of the GNU General Public License as published by 32.11 + * the Free Software Foundation; either version 2 of the License, or 32.12 + * (at your option) any later version. 32.13 + * 32.14 + * This program is distributed in the hope that it will be useful, 32.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 32.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 32.17 + * GNU General Public License for more details. 32.18 + * 32.19 + * You should have received a copy of the GNU General Public License 32.20 + * along with this program; if not, write to the Free Software 32.21 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 32.22 + * 32.23 + * $Id: Define.java,v 1.7 2006/12/14 14:35:00 mikhail Exp $ 32.24 */ 32.25 32.26 package kryshen.tema.functions; 32.27 @@ -11,9 +25,15 @@ 32.28 32.29 import kryshen.tema.*; 32.30 32.31 +/** 32.32 + * Define function implementation. 32.33 + * 32.34 + * @author Mikhail A. Kryshen 32.35 + */ 32.36 public class Define extends Function { 32.37 + public static final Function DEFINE = new Define(); 32.38 + 32.39 public Define() { 32.40 - super("define"); 32.41 } 32.42 32.43 public int invoke(FunctionDataParser fdp, Writer out) 32.44 @@ -22,37 +42,42 @@ 32.45 final String arg0 = fdp.getNextArg(); 32.46 final String data = fdp.getData(); 32.47 32.48 - Function newFunction = new Function(arg0) { 32.49 + Function newFunction = new Function() { 32.50 public int invoke(final FunctionDataParser fdp, final Writer out) 32.51 throws IOException, TemplateException { 32.52 - 32.53 + 32.54 TemplateParser functionParser = 32.55 new TemplateParser(fdp.getTemplateParser()); 32.56 32.57 - functionParser.registerFunction(new Function("nextarg") { 32.58 - public int invoke(FunctionDataParser unusedFdp, 32.59 - final Writer out) 32.60 - throws IOException, TemplateException { 32.61 + functionParser.registerFunction 32.62 + ("nextarg", new Function() { 32.63 + public int invoke(FunctionDataParser unusedFdp, 32.64 + final Writer out) 32.65 + throws IOException, TemplateException { 32.66 + 32.67 + return fdp.parseNextArg(out); 32.68 + } 32.69 + }); 32.70 + 32.71 + functionParser.registerFunction 32.72 + ("data",new Function() { 32.73 + public int invoke(FunctionDataParser unusedFdp, 32.74 + final Writer out) 32.75 + throws IOException, TemplateException { 32.76 + 32.77 + return fdp.parseData(out); 32.78 + } 32.79 + }); 32.80 + 32.81 + TemplateReader dataReader = new TemplateReader 32.82 + (new StringReader(data), fdp.getTemplateReader()); 32.83 32.84 - return fdp.parseNextArg(out); 32.85 - } 32.86 - }); 32.87 - 32.88 - functionParser.registerFunction(new Function("data") { 32.89 - public int invoke(FunctionDataParser unusedFdp, 32.90 - final Writer out) 32.91 - throws IOException, TemplateException { 32.92 - 32.93 - return fdp.parseData(out); 32.94 - } 32.95 - }); 32.96 - 32.97 - return functionParser.parse(new StringReader(data), out); 32.98 + return functionParser.parse(dataReader, out); 32.99 } 32.100 }; 32.101 - 32.102 - fdp.getTemplateParser().registerFunction(newFunction); 32.103 - 32.104 + 32.105 + fdp.getTemplateParser().registerFunction(arg0, newFunction); 32.106 + 32.107 out.write(arg0); 32.108 return 1; 32.109 }
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 33.2 +++ b/src/kryshen/tema/functions/IO.java Thu Dec 14 23:22:05 2006 +0300 33.3 @@ -0,0 +1,163 @@ 33.4 +/* 33.5 + * Copyright (C) 2005, 2006 Mikhail A. Kryshen 33.6 + * 33.7 + * This program is free software; you can redistribute it and/or modify 33.8 + * it under the terms of the GNU General Public License as published by 33.9 + * the Free Software Foundation; either version 2 of the License, or 33.10 + * (at your option) any later version. 33.11 + * 33.12 + * This program is distributed in the hope that it will be useful, 33.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 33.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 33.15 + * GNU General Public License for more details. 33.16 + * 33.17 + * You should have received a copy of the GNU General Public License 33.18 + * along with this program; if not, write to the Free Software 33.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 33.20 + * 33.21 + * $Id: IO.java,v 1.4 2006/12/14 15:59:49 mikhail Exp $ 33.22 + */ 33.23 + 33.24 +package kryshen.tema.functions; 33.25 + 33.26 +import java.io.*; 33.27 +import java.util.*; 33.28 + 33.29 +import kryshen.tema.*; 33.30 + 33.31 +/** 33.32 + * I/O functions. 33.33 + */ 33.34 +public class IO { 33.35 + public static final Function COPY = 33.36 + new Function() { 33.37 + public int invoke(FunctionDataParser fdp, Writer out) 33.38 + throws IOException, TemplateException { 33.39 + 33.40 + String arg0 = fdp.getNextArg(); 33.41 + String arg1 = fdp.getNextArg(); 33.42 + 33.43 + File source = new File 33.44 + (Tema.getProperty("resource_base"), arg0); 33.45 + File dest = new File(arg1); 33.46 + 33.47 + try { 33.48 + copyFile(source, dest); 33.49 + } catch (IOException e) { 33.50 + System.err.println(e); 33.51 + return 0; 33.52 + } 33.53 + out.write(arg1); 33.54 + return 1; 33.55 + } 33.56 + }; 33.57 + 33.58 + public static final Function WRITE = 33.59 + new Function() { 33.60 + public int invoke(FunctionDataParser fdp, Writer out) 33.61 + throws IOException, TemplateException { 33.62 + 33.63 + String arg0 = fdp.getNextArg(); 33.64 + 33.65 + System.err.println("Writing " + arg0 + "..."); 33.66 + 33.67 + Writer fw; 33.68 + 33.69 + try { 33.70 + fw = Tema.createFileWriter(arg0); 33.71 + } catch (IOException e) { 33.72 + System.err.println(e); 33.73 + //throw new TemplateException(e.getMessage(), e, in); 33.74 + return 0; 33.75 + } 33.76 + 33.77 + try { 33.78 + fdp.parseData(fw); 33.79 + } finally { 33.80 + fw.close(); 33.81 + } 33.82 + 33.83 + out.write(arg0); 33.84 + 33.85 + System.err.println("Saved " + arg0 + "."); 33.86 + return 1; 33.87 + } 33.88 + }; 33.89 + 33.90 + public static final Function READ = 33.91 + new Function() { 33.92 + public int invoke(FunctionDataParser fdp, Writer out) 33.93 + throws IOException, TemplateException { 33.94 + 33.95 + String filename = fdp.getData(); 33.96 + String file; 33.97 + 33.98 + try { 33.99 + file = Tema.readFile(new File(filename)); 33.100 + } catch (IOException e) { 33.101 + System.err.println(e); 33.102 + //throw new TemplateException(e.getMessage(), e, in); 33.103 + return 0; 33.104 + } 33.105 + 33.106 + out.write(file); 33.107 + return 1; 33.108 + } 33.109 + }; 33.110 + 33.111 + public static final Function INCLUDE = 33.112 + new Function() { 33.113 + public int invoke(FunctionDataParser fdp, Writer out) 33.114 + throws IOException, TemplateException { 33.115 + 33.116 + String filename = fdp.getData(); 33.117 + 33.118 + TemplateReader fin; 33.119 + 33.120 + try { 33.121 + fin = Tema.createTemplateReader(new File(filename)); 33.122 + } catch (IOException e) { 33.123 + throw new TemplateException(e.getMessage(), e, 33.124 + fdp.getTemplateReader()); 33.125 + } 33.126 + 33.127 + int r = fdp.getTemplateParser().parse(fin, out); 33.128 + 33.129 + fin.close(); 33.130 + return r; 33.131 + } 33.132 + }; 33.133 + 33.134 + /** 33.135 + * Update file (copy if newer). 33.136 + * 33.137 + * @param src source file. 33.138 + * @param dest destination file. 33.139 + * 33.140 + * @trows IOException on copying error. 33.141 + */ 33.142 + private static void copyFile(File src, File dest) throws IOException { 33.143 + System.err.print("Copying " + src + "... "); 33.144 + 33.145 + if (src.lastModified() < dest.lastModified()) { 33.146 + System.err.println(dest + " is up to date."); 33.147 + return; 33.148 + } 33.149 + 33.150 + File parent = dest.getParentFile(); 33.151 + if (parent != null) parent.mkdirs(); 33.152 + 33.153 + InputStream in = new FileInputStream(src); 33.154 + OutputStream out = new FileOutputStream(dest); 33.155 + 33.156 + byte[] buffer = new byte[1024]; 33.157 + int len; 33.158 + while ((len = in.read(buffer)) > 0) { 33.159 + out.write(buffer, 0, len); 33.160 + } 33.161 + in.close(); 33.162 + out.close(); 33.163 + 33.164 + System.err.println("saved " + dest + "."); 33.165 + } 33.166 +}
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 34.2 +++ b/src/kryshen/tema/functions/ImageConverter.java Thu Dec 14 23:22:05 2006 +0300 34.3 @@ -0,0 +1,188 @@ 34.4 +/* 34.5 + * Copyright (C) 2005, 2006 Mikhail A. Kryshen 34.6 + * 34.7 + * This program is free software; you can redistribute it and/or modify 34.8 + * it under the terms of the GNU General Public License as published by 34.9 + * the Free Software Foundation; either version 2 of the License, or 34.10 + * (at your option) any later version. 34.11 + * 34.12 + * This program is distributed in the hope that it will be useful, 34.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 34.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 34.15 + * GNU General Public License for more details. 34.16 + * 34.17 + * You should have received a copy of the GNU General Public License 34.18 + * along with this program; if not, write to the Free Software 34.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 34.20 + * 34.21 + * $Id: ImageConverter.java,v 1.4 2006/12/14 19:44:32 mikhail Exp $ 34.22 + */ 34.23 + 34.24 +package kryshen.tema.functions; 34.25 + 34.26 +import java.util.*; 34.27 +import java.io.*; 34.28 +import java.awt.*; 34.29 +import java.awt.image.*; 34.30 +import java.awt.geom.AffineTransform; 34.31 +import javax.imageio.*; 34.32 +import javax.imageio.stream.*; 34.33 + 34.34 +import kryshen.tema.*; 34.35 + 34.36 +/** 34.37 + * Convert images to specified format. 34.38 + * 34.39 + * @author Mikhail A. Kryshen 34.40 + */ 34.41 +public class ImageConverter extends Function { 34.42 + 34.43 + public static final Function IMAGE = new ImageConverter(); 34.44 + 34.45 + public int invoke(FunctionDataParser fdp, Writer out) 34.46 + throws IOException, TemplateException { 34.47 + 34.48 + String arg0 = fdp.getNextArg(); 34.49 + String arg1 = fdp.getNextArg(); 34.50 + String arg2 = fdp.getNextArg(); 34.51 + int arg3 = fdp.hasMoreData() ? 34.52 + Integer.parseInt(fdp.getNextArg()) : -1; 34.53 + int arg4 = fdp.hasMoreData() ? 34.54 + Integer.parseInt(fdp.getNextArg()) : -1; 34.55 + 34.56 + File source = new File 34.57 + (Tema.getProperty("resource_base"), arg0); 34.58 + 34.59 + try { 34.60 + convert 34.61 + (source, /* source file */ 34.62 + new File(arg1), /* dest file */ 34.63 + arg2, /* format */ 34.64 + arg3, /* max width */ 34.65 + arg4); /* max height */ 34.66 + } catch (Exception e) { 34.67 + System.err.println(e); 34.68 + return 0; 34.69 + } 34.70 + 34.71 + out.write(arg1); 34.72 + return 1; 34.73 + } 34.74 + 34.75 + public static void convert(File source, File dest, String format, 34.76 + int maxWidth, int maxHeight) 34.77 + throws IOException, InterruptedException { 34.78 + 34.79 + System.err.print("Converting image " + source + "... "); 34.80 + 34.81 + if (source.lastModified() < dest.lastModified()) { 34.82 + System.err.println(dest + " is up to date."); 34.83 + return; 34.84 + } 34.85 + 34.86 + BufferedImage image = ImageIO.read(source); 34.87 + 34.88 + //int type = image.getType(); 34.89 + //final int type = BufferedImage.TYPE_INT_RGB; 34.90 + //ColorModel cm = image.getColorModel(); 34.91 + 34.92 + int w = image.getWidth(null); 34.93 + int h = image.getHeight(null); 34.94 + 34.95 + //boolean scale = false; 34.96 + 34.97 + float scale = 1f; 34.98 + 34.99 + if (maxWidth > 0 && w > maxWidth) 34.100 + scale = (float)maxWidth / w; 34.101 + 34.102 + if (maxHeight > 0 && h * scale > maxHeight) 34.103 + scale = (float)maxHeight / h; 34.104 + 34.105 + if (scale != 1f) { 34.106 + w *= scale; h *= scale; 34.107 + 34.108 +// ColorModel cm = image.getColorModel(); 34.109 +// boolean alphaPremultiplied = cm.isAlphaPremultiplied(); 34.110 +// WritableRaster raster = cm.createCompatibleWritableRaster(w, h); 34.111 +// BufferedImage scaled = new BufferedImage 34.112 +// (cm, raster, alphaPremultiplied, null); 34.113 + 34.114 +// BufferedImage scaled = new BufferedImage(w, h, image.getType()); 34.115 + 34.116 + 34.117 + Image scaled = image.getScaledInstance(w, h, Image.SCALE_SMOOTH); 34.118 + 34.119 + ColorModel cm = image.getColorModel(); 34.120 + boolean alphaPremultiplied = image.isAlphaPremultiplied(); 34.121 + WritableRaster raster = cm.createCompatibleWritableRaster(w, h); 34.122 + image = new BufferedImage(cm, raster, alphaPremultiplied, null); 34.123 + 34.124 + Graphics g = image.getGraphics(); 34.125 + g.drawImage(scaled, 0, 0, null); 34.126 + g.dispose(); 34.127 + 34.128 +// image = scale(image, scaled, scale); 34.129 +// Graphics2D g = scaled.createGraphics(); 34.130 +// g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, 34.131 +// RenderingHints.VALUE_INTERPOLATION_BILINEAR); 34.132 +// System.err.print(" " + g.drawImage(image, 0, 0, w, h, null) + " "); 34.133 +// g.dispose(); 34.134 +// image = scaled; 34.135 + } 34.136 + 34.137 + File parent = dest.getParentFile(); 34.138 + if (parent != null) parent.mkdirs(); 34.139 + 34.140 + ImageIO.write(image, format, dest); 34.141 + System.err.println("saved " + dest + "."); 34.142 + } 34.143 + 34.144 +// public static ColorModel getColorModel(Image image) 34.145 +// throws InterruptedException { 34.146 + 34.147 +// PixelGrabber grabby = new PixelGrabber(image, 0, 0, 1, 1, false); 34.148 +// if (!grabby.grabPixels()) 34.149 +// throw new RuntimeException("pixel grab fails"); 34.150 +// return grabby.getColorModel(); 34.151 +// } 34.152 + 34.153 +// private static BufferedImage scale(BufferedImage image, 34.154 +// BufferedImage dest, 34.155 +// float scale) { 34.156 + 34.157 +// AffineTransform tx = new AffineTransform(); 34.158 +// tx.scale(scale, scale); 34.159 + 34.160 +// AffineTransformOp op = new AffineTransformOp 34.161 +// (tx, AffineTransformOp.TYPE_BILINEAR); 34.162 + 34.163 +// return op.filter(image, dest); 34.164 +// } 34.165 + 34.166 + // TEST 34.167 + public static void main(String[] args) 34.168 + throws IOException, InterruptedException { 34.169 + 34.170 + convert(new File(args[0]), new File(args[1]), "png", 300, 300); 34.171 + } 34.172 + 34.173 + 34.174 +// public static BufferedImage toBufferedImage(Image image, ColorModel cm) { 34.175 +// if (image instanceof BufferedImage) 34.176 +// return (BufferedImage)image; 34.177 + 34.178 +// int w = image.getWidth(null); 34.179 +// int h = image.getHeight(null); 34.180 + 34.181 +// boolean alphaPremultiplied = cm.isAlphaPremultiplied(); 34.182 +// WritableRaster raster = cm.createCompatibleWritableRaster(w, h); 34.183 +// BufferedImage result = new BufferedImage(cm, raster, alphaPremultiplied, null); 34.184 +// Graphics2D g = result.createGraphics(); 34.185 + 34.186 +// g.drawImage(image, 0, 0, null); 34.187 +// g.dispose(); 34.188 + 34.189 +// return result; 34.190 +// } 34.191 +}
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 35.2 +++ b/src/kryshen/tema/functions/Logics.java Thu Dec 14 23:22:05 2006 +0300 35.3 @@ -0,0 +1,75 @@ 35.4 +/* 35.5 + * Copyright (C) 2006 Mikhail A. Kryshen 35.6 + * 35.7 + * This program is free software; you can redistribute it and/or modify 35.8 + * it under the terms of the GNU General Public License as published by 35.9 + * the Free Software Foundation; either version 2 of the License, or 35.10 + * (at your option) any later version. 35.11 + * 35.12 + * This program is distributed in the hope that it will be useful, 35.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 35.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 35.15 + * GNU General Public License for more details. 35.16 + * 35.17 + * You should have received a copy of the GNU General Public License 35.18 + * along with this program; if not, write to the Free Software 35.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 35.20 + * 35.21 + * $Id: Logics.java,v 1.6 2006/12/14 14:39:26 mikhail Exp $ 35.22 + */ 35.23 + 35.24 +package kryshen.tema.functions; 35.25 + 35.26 +import java.io.*; 35.27 +import java.util.*; 35.28 + 35.29 +import kryshen.tema.*; 35.30 + 35.31 +/** 35.32 + * Logical and conditional functions. 35.33 + * 35.34 + * @author Mikhail A. Kryshen 35.35 + */ 35.36 +public class Logics { 35.37 + public static final Function FALSE = 35.38 + new Function() { 35.39 + public int invoke(FunctionDataParser fdp, Writer out) 35.40 + throws IOException, TemplateException { 35.41 + 35.42 + fdp.parseData(out); 35.43 + return 0; 35.44 + } 35.45 + }; 35.46 + 35.47 + public static final Function TRUE = 35.48 + new Function() { 35.49 + public int invoke(FunctionDataParser fdp, Writer out) 35.50 + throws IOException, TemplateException { 35.51 + 35.52 + fdp.parseData(out); 35.53 + return 1; 35.54 + } 35.55 + }; 35.56 + 35.57 + /** 35.58 + * Outputs it's data it has non-zero value. 35.59 + */ 35.60 + public static final Function OPTIONAL = 35.61 + new Function() { 35.62 + public int invoke(FunctionDataParser fdp, Writer out) 35.63 + throws IOException, TemplateException { 35.64 + 35.65 + StringWriter sw = new StringWriter(); 35.66 + int s = fdp.parseData(sw); 35.67 + sw.close(); 35.68 + String data = sw.toString(); 35.69 + 35.70 + if (s != 0) { 35.71 + out.write(data); 35.72 + return 1; 35.73 + } else { 35.74 + return 0; 35.75 + } 35.76 + } 35.77 + }; 35.78 +}
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 36.2 +++ b/src/kryshen/tema/functions/ReplaceWriter.java Thu Dec 14 23:22:05 2006 +0300 36.3 @@ -0,0 +1,154 @@ 36.4 +/* 36.5 + * Copyright (C) 2006 Mikhail A. Kryshen 36.6 + * 36.7 + * This program is free software; you can redistribute it and/or modify 36.8 + * it under the terms of the GNU General Public License as published by 36.9 + * the Free Software Foundation; either version 2 of the License, or 36.10 + * (at your option) any later version. 36.11 + * 36.12 + * This program is distributed in the hope that it will be useful, 36.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 36.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 36.15 + * GNU General Public License for more details. 36.16 + * 36.17 + * You should have received a copy of the GNU General Public License 36.18 + * along with this program; if not, write to the Free Software 36.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 36.20 + * 36.21 + * $Id: ReplaceWriter.java,v 1.2 2006/12/14 14:39:26 mikhail Exp $ 36.22 + */ 36.23 + 36.24 +package kryshen.tema.functions; 36.25 + 36.26 +import java.io.Writer; 36.27 +import java.io.FilterWriter; 36.28 +import java.io.IOException; 36.29 + 36.30 +import java.util.LinkedList; 36.31 +import java.util.Iterator; 36.32 + 36.33 +/** 36.34 + * FilterWriter which replaces characters with escape strings. 36.35 + * 36.36 + * @author Mikhail A. Kryshen 36.37 + */ 36.38 +class ReplaceWriter extends FilterWriter { 36.39 + private String[] patterns; 36.40 + private String[] replaces; 36.41 + 36.42 + private String prefix; 36.43 + private String postfix; 36.44 + 36.45 + private int maxPatternLength = 0; 36.46 + 36.47 + /** Have this Writer processed any data? */ 36.48 + private boolean processedData = false; 36.49 + 36.50 + private StringBuffer buffer = new StringBuffer(); 36.51 + 36.52 + public ReplaceWriter(Writer w, String pattern, String replace) { 36.53 + this(w, new String[]{pattern}, new String[]{replace}); 36.54 + } 36.55 + 36.56 + public ReplaceWriter(Writer w, String pattern, String replace, 36.57 + String prefix, String postfix) { 36.58 + 36.59 + this(w, new String[]{pattern}, new String[]{replace}, 36.60 + prefix, postfix); 36.61 + } 36.62 + 36.63 + public ReplaceWriter(Writer w, String[] patterns, String[] replaces) { 36.64 + this(w, patterns, replaces, null, null); 36.65 + } 36.66 + 36.67 + public ReplaceWriter(Writer w, String[] patterns, String[] replaces, 36.68 + String prefix, String postfix) { 36.69 + super(w); 36.70 + 36.71 + this.patterns = patterns; 36.72 + this.replaces = replaces; 36.73 + 36.74 + this.prefix = prefix; 36.75 + this.postfix = postfix; 36.76 + 36.77 + for (int i = 0; i < patterns.length; i++) { 36.78 + int length = patterns[i].length(); 36.79 + if (length > maxPatternLength) 36.80 + maxPatternLength = length; 36.81 + } 36.82 + } 36.83 + 36.84 + private boolean processBuffer(int minLength) throws IOException { 36.85 + if (buffer.length() == 0) return false; 36.86 + 36.87 + if (!processedData) { 36.88 + if (prefix != null) 36.89 + super.write(prefix, 0, prefix.length()); 36.90 + processedData = true; 36.91 + } 36.92 + 36.93 + int k; 36.94 + for (k = 0; minLength + k < buffer.length(); k++) { 36.95 + for (int i = 0; i < patterns.length; i++) { 36.96 + String pattern = patterns[i]; 36.97 + int length = pattern.length(); 36.98 + 36.99 + if (length + k > buffer.length()) 36.100 + continue; 36.101 + 36.102 + boolean match = true; 36.103 + 36.104 + for (int j = 0; j < length; j++) { 36.105 + if (pattern.charAt(j) != buffer.charAt(j + k)) { 36.106 + match = false; 36.107 + break; 36.108 + } 36.109 + } 36.110 + 36.111 + if (match) { 36.112 + super.write(buffer.substring(0, k), 0, k); 36.113 + buffer.delete(0, k + length); 36.114 + super.write(replaces[i], 0, replaces[i].length()); 36.115 + return true; 36.116 + } 36.117 + } 36.118 + } 36.119 + 36.120 + super.write(buffer.substring(0, k), 0, k); 36.121 + buffer.delete(0, k); 36.122 + 36.123 + return false; 36.124 + } 36.125 + 36.126 + public void write(int c) throws IOException { 36.127 + buffer.append((char)c); 36.128 + processBuffer(maxPatternLength); 36.129 + } 36.130 + 36.131 + public void write(char[] cbuf, int off, int len) throws IOException { 36.132 + for (int i = off; i < off + len; i++) { 36.133 + buffer.append(cbuf[i]); 36.134 + } 36.135 + processBuffer(maxPatternLength); 36.136 + } 36.137 + 36.138 + public void write(String str, int off, int len) throws IOException { 36.139 + buffer.append(str.substring(off, off + len)); 36.140 + processBuffer(maxPatternLength); 36.141 + } 36.142 + 36.143 + public void finish() throws IOException { 36.144 + while (processBuffer(0)); 36.145 + 36.146 +// super.write(buffer.toString(), 0, buffer.length()); 36.147 +// buffer.delete(0, buffer.length()); 36.148 + 36.149 + if (processedData && postfix != null) 36.150 + super.write(postfix, 0, postfix.length()); 36.151 + } 36.152 + 36.153 + public void close() throws IOException { 36.154 + finish(); 36.155 + super.close(); 36.156 + } 36.157 +}
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 37.2 +++ b/src/kryshen/tema/functions/Standard.java Thu Dec 14 23:22:05 2006 +0300 37.3 @@ -0,0 +1,258 @@ 37.4 +/* 37.5 + * Copyright (C) 2005, 2006 Mikhail A. Kryshen 37.6 + * 37.7 + * This program is free software; you can redistribute it and/or modify 37.8 + * it under the terms of the GNU General Public License as published by 37.9 + * the Free Software Foundation; either version 2 of the License, or 37.10 + * (at your option) any later version. 37.11 + * 37.12 + * This program is distributed in the hope that it will be useful, 37.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 37.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 37.15 + * GNU General Public License for more details. 37.16 + * 37.17 + * You should have received a copy of the GNU General Public License 37.18 + * along with this program; if not, write to the Free Software 37.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 37.20 + * 37.21 + * $Id: Standard.java,v 1.5 2006/12/14 14:39:26 mikhail Exp $ 37.22 + */ 37.23 + 37.24 +package kryshen.tema.functions; 37.25 + 37.26 +import java.io.*; 37.27 +import java.util.*; 37.28 +import java.net.*; 37.29 + 37.30 +import java.sql.SQLException; 37.31 +import java.sql.PreparedStatement; 37.32 + 37.33 +import kryshen.tema.*; 37.34 + 37.35 +/** 37.36 + * Standard TEMA functions. 37.37 + */ 37.38 +public class Standard { 37.39 + public static final Function SET = 37.40 + new Function() { 37.41 + public int invoke(FunctionDataParser fdp, Writer out) 37.42 + throws IOException, TemplateException { 37.43 + 37.44 + String arg0 = fdp.getNextArg(); 37.45 + String arg1 = fdp.getData(); 37.46 + 37.47 + fdp.getTemplateParser().setValue(arg0, arg1); 37.48 + 37.49 + out.write(arg0); 37.50 + return 1; 37.51 + } 37.52 + }; 37.53 + 37.54 + /* prepare:qury_name sql_statement */ 37.55 + public static final Function PREPARE = 37.56 + new Function() { 37.57 + public int invoke(FunctionDataParser fdp, Writer out) 37.58 + throws IOException, TemplateException { 37.59 + 37.60 + String arg0 = fdp.getNextArg(); 37.61 + String data = fdp.getData(); 37.62 + 37.63 + PreparedStatement statement; 37.64 + 37.65 + try { 37.66 + statement = Tema.getDbConnection() 37.67 + .prepareStatement(data); 37.68 + } catch (SQLException e) { 37.69 + throw new TemplateException 37.70 + (e.getMessage(), e, fdp.getTemplateReader()); 37.71 + } 37.72 + 37.73 + fdp.getTemplateParser().setValue(arg0, statement); 37.74 + 37.75 + out.write(arg0); 37.76 + return 1; 37.77 + } 37.78 + }; 37.79 + 37.80 + /* query:sql_query template arg1 arg2 ... argN */ 37.81 + public static final Function QUERY = 37.82 + new Function() { 37.83 + public int invoke(FunctionDataParser fdp, Writer out) 37.84 + throws IOException, TemplateException { 37.85 + 37.86 + String arg0 = fdp.getNextArg(); 37.87 + String arg1 = fdp.getNextArg(); 37.88 + List<String> args = fdp.getArgs(); 37.89 + 37.90 + TemplateParser tp = fdp.getTemplateParser(); 37.91 + 37.92 + TemplateReader tr = 37.93 + new TemplateReader(new StringReader(arg1), 37.94 + fdp.getTemplateReader()); 37.95 + 37.96 + try { 37.97 + return Tema.query 37.98 + (tr, (PreparedStatement)tp.getValue(arg0), 37.99 + args, tp, out); 37.100 + } catch (SQLException e) { 37.101 + throw new TemplateException 37.102 + (e.getMessage(), e, fdp.getTemplateReader()); 37.103 + } 37.104 + } 37.105 + }; 37.106 + 37.107 + public static final Function REPLACE = 37.108 + new Function() { 37.109 + public int invoke(FunctionDataParser fdp, Writer out) 37.110 + throws IOException, TemplateException { 37.111 + 37.112 + String arg0 = fdp.getNextArg(); 37.113 + String arg1 = fdp.getNextArg(); 37.114 + 37.115 + ReplaceWriter rw = new ReplaceWriter(out, arg0, arg1); 37.116 + 37.117 + int ret = fdp.parseData(rw); 37.118 + rw.finish(); 37.119 + return ret; 37.120 + } 37.121 + }; 37.122 + 37.123 + public static final Function LOAD = 37.124 + 37.125 + new Function() { 37.126 + public int invoke(FunctionDataParser fdp, Writer out) 37.127 + throws IOException, TemplateException { 37.128 + 37.129 + final String name = fdp.getNextArg(); 37.130 + final String className = fdp.getNextArg(); 37.131 + 37.132 + List<URL> urls = new ArrayList<URL>(1); 37.133 + 37.134 + while (fdp.hasMoreData()) { 37.135 + urls.add(new URL(fdp.getNextArg())); 37.136 + } 37.137 + 37.138 + ClassLoader loader = this.getClass().getClassLoader(); 37.139 + 37.140 + if (urls.size() > 0) { 37.141 + loader = new URLClassLoader 37.142 + (urls.toArray(new URL[0]), loader); 37.143 + } 37.144 + 37.145 + Class<Function> functionClass; 37.146 + Function function; 37.147 + 37.148 + try { 37.149 + functionClass = loadFunctionClass(loader, className); 37.150 + } catch (ClassNotFoundException e) { 37.151 + throw new TemplateException 37.152 + ("Class not found", e, fdp.getTemplateReader()); 37.153 + } catch (ClassCastException e) { 37.154 + throw new TemplateException 37.155 + ("Not a function class", e, fdp.getTemplateReader()); 37.156 + } 37.157 + 37.158 + try { 37.159 + function = functionClass.newInstance(); 37.160 + } catch (InstantiationException e) { 37.161 + throw new TemplateException 37.162 + ("Could not load class", e, fdp.getTemplateReader()); 37.163 + } catch (IllegalAccessException e) { 37.164 + throw new TemplateException 37.165 + ("Could not load class", e, fdp.getTemplateReader()); 37.166 + } 37.167 + 37.168 + fdp.getTemplateParser().registerFunction(name, function); 37.169 + 37.170 + 37.171 + out.write(name); 37.172 + return 1; 37.173 + } 37.174 + }; 37.175 + 37.176 + public static final Function NULL_OUTPUT = 37.177 + new Function() { 37.178 + public int invoke(FunctionDataParser fdp, Writer out) 37.179 + throws IOException, TemplateException { 37.180 + 37.181 + /* Write nothing. */ 37.182 + return fdp.parseData(new Writer() { 37.183 + public void close() {} 37.184 + public void flush() {} 37.185 + public void write(char[] cbuf, int off, int len) {} 37.186 + }); 37.187 + } 37.188 + }; 37.189 + 37.190 + public static final Function XML_ESCAPE = 37.191 + new Function() { 37.192 + public int invoke(FunctionDataParser fdp, Writer out) 37.193 + throws IOException, TemplateException { 37.194 + 37.195 + final String[] chars = {"&", "<", ">", "`", "\""}; 37.196 + final String[] escape = {"&", "<", ">", "'", """}; 37.197 + 37.198 + ReplaceWriter rw = new ReplaceWriter(out, chars, escape); 37.199 + 37.200 + int ret = fdp.parseData(rw); 37.201 + rw.finish(); 37.202 + return ret; 37.203 + } 37.204 + }; 37.205 + 37.206 + public static final Function XML_CDATA = 37.207 + new Function() { 37.208 + public int invoke(FunctionDataParser fdp, Writer out) 37.209 + throws IOException, TemplateException { 37.210 + 37.211 + ReplaceWriter rw = new ReplaceWriter 37.212 + (out, "]]>", "]]]><![CDATA[]>", "<![CDATA[", "]]>"); 37.213 + 37.214 + int ret = fdp.parseData(rw); 37.215 + rw.finish(); 37.216 + return ret; 37.217 + } 37.218 + }; 37.219 + 37.220 + 37.221 + @SuppressWarnings("unchecked") 37.222 + private static Class<Function> loadFunctionClass 37.223 + (ClassLoader loader, String className) 37.224 + throws ClassNotFoundException { 37.225 + 37.226 + return (Class<Function>)loader.loadClass(className); 37.227 + } 37.228 + 37.229 + /** 37.230 + * Update file (copy if newer). 37.231 + * 37.232 + * @param src source file. 37.233 + * @param dest destination file. 37.234 + * 37.235 + * @trows IOException on copying error. 37.236 + */ 37.237 + private static void copyFile(File src, File dest) throws IOException { 37.238 + System.err.print("Copying " + src + "... "); 37.239 + 37.240 + if (src.lastModified() < dest.lastModified()) { 37.241 + System.err.println(dest + " is up to date."); 37.242 + return; 37.243 + } 37.244 + 37.245 + File parent = dest.getParentFile(); 37.246 + if (parent != null) parent.mkdirs(); 37.247 + 37.248 + InputStream in = new FileInputStream(src); 37.249 + OutputStream out = new FileOutputStream(dest); 37.250 + 37.251 + byte[] buffer = new byte[1024]; 37.252 + int len; 37.253 + while ((len = in.read(buffer)) > 0) { 37.254 + out.write(buffer, 0, len); 37.255 + } 37.256 + in.close(); 37.257 + out.close(); 37.258 + 37.259 + System.err.println("saved " + dest + "."); 37.260 + } 37.261 +}
38.1 Binary file test/Hello.class has changed
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 39.2 +++ b/test/Hello.java Thu Dec 14 23:22:05 2006 +0300 39.3 @@ -0,0 +1,21 @@ 39.4 +import java.io.Writer; 39.5 +import java.io.IOException; 39.6 +import kryshen.tema.*; 39.7 + 39.8 +/** 39.9 + * Test function class. 39.10 + * 39.11 + * @author Mikhail A. Kryshen 39.12 + */ 39.13 +public class Hello extends Function { 39.14 + public Hello() {} 39.15 + 39.16 + public int invoke(FunctionDataParser fdp, Writer out) 39.17 + throws IOException, TemplateException { 39.18 + 39.19 + out.write("Hello, "); 39.20 + fdp.parseData(out); 39.21 + 39.22 + return 1; 39.23 + } 39.24 +}
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 40.2 +++ b/test/demo Thu Dec 14 23:22:05 2006 +0300 40.3 @@ -0,0 +1,4 @@ 40.4 +#!/bin/sh 40.5 + 40.6 +#java -jar ../dist/tema.jar 40.7 +java -classpath .:../dist/tema.jar kryshen.tema.Tema
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 41.2 +++ b/test/demo.bat Thu Dec 14 23:22:05 2006 +0300 41.3 @@ -0,0 +1,1 @@ 41.4 +java -classpath .:..\dist\tema.jar kryshen.tema.Tema
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 42.2 +++ b/test/include.template Thu Dec 14 23:22:05 2006 +0300 42.3 @@ -0,0 +1,1 @@ 42.4 +<%define\test test arg1:[%nextarg:%], test arg2:[%nextarg:%], test data:[%data:%].%> 42.5 \ No newline at end of file
43.1 --- a/test/inctest.template Tue May 16 18:04:09 2006 +0400 43.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 43.3 @@ -1,1 +0,0 @@ 43.4 -<%test:1 2 3%>
44.1 --- a/test/macrotest Tue May 16 18:04:09 2006 +0400 44.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 44.3 @@ -1,3 +0,0 @@ 44.4 -#!/bin/sh 44.5 - 44.6 -java -jar ../dist/tema.jar
45.1 --- a/test/main.template Tue May 16 18:04:09 2006 +0400 45.2 +++ b/test/main.template Thu Dec 14 23:22:05 2006 +0300 45.3 @@ -1,3 +1,28 @@ 45.4 -<%define`test [%nextarg:%]+[%nextarg:%]=[%data:]%> 45.5 -<%include`inctest.template%> 45.6 -<%test:<%test:ab cd x%> [%\<%test\1 2 3%>%] y%> 45.7 +[%!\ UTF-8 text %] 45.8 + 45.9 +п▓я▀п╡п╬п╢ я┌п╣п╨я│я┌п╟: 45.10 +test text 45.11 + 45.12 +п▓я▀п╡п╬п╢ я│п©п╣я├п╦п╟п╩я▄п╫я▀я┘ я│п╦п╪п╡п╬п╩п╬п╡: 45.13 +[%\<%test%>%] 45.14 + 45.15 +п▓п╨п╩я▌я┤п╣п╫п╦п╣ я└п╟п╧п╩п╟ я│ п╬п╠я┼я▐п╡п╩п╣п╫п╦п╣п╪ я└я┐п╫п╨я├п╦п╦: 45.16 +<%include:include.template%> 45.17 + 45.18 +п▓я▀п╥п╬п╡ п╫п╬п╡п╬п╧ я└я┐п╫п╨я├п╦п╦: 45.19 +<%test:1 2 3%> 45.20 + 45.21 +п╒п╣я│я┌п╦я─п╬п╡п╟п╫п╦п╣ read: 45.22 +<%read\include.template%> 45.23 + 45.24 +п≈п╟пЁя─я┐п╥п╨п╟ я└я┐п╫п╨я├п╦п╦ п╦п╥ п╨п╩п╟я│я│п╟: 45.25 +<%load\hello Hello%> 45.26 + 45.27 +п▓я▀п©п╬п╩п╣п╫п╣п╫п╦п╣ п╥п╟пЁя─я┐п╤п╣п╫п╫п╬п╧ я└я┐п╫п╨я├п╦п╦: 45.28 +<%hello\TEMA%> 45.29 + 45.30 +пёя│п╩п╬п╡п╫п╬п╣ п╡я▀п©п╬п╩п╫п╣п╫п╦п╣: 45.31 +<%optional:<%true:%>True%> <%optional:<%false:%>False%> 45.32 + 45.33 +п╒п╣я│я┌п╦я─п╬п╡п╟п╫п╦п╣ xml_escape: 45.34 +<%xml_escape\x < a & b%>
46.1 --- a/test/tema.properties Tue May 16 18:04:09 2006 +0400 46.2 +++ b/test/tema.properties Thu Dec 14 23:22:05 2006 +0300 46.3 @@ -1,16 +1,16 @@ 46.4 # Data source configuration 46.5 -# resource : jdbc:odbc:biotopes-data 46.6 +# resource : jdbc:odbc:database 46.7 # driver : sun.jdbc.odbc.JdbcOdbcDriver 46.8 46.9 # Base directory for images and files 46.10 -# resource_base : C:\\biotopes\\db 46.11 +# resource_base : . 46.12 46.13 # Template to start processing with 46.14 main_template : main.template 46.15 46.16 # File encodings 46.17 -# input_encoding : ISO-8859-5 46.18 -# output_encoding : ISO-8859-5 46.19 +input_encoding : UTF-8 46.20 +output_encoding : UTF-8 46.21 46.22 # Cache templates 46.23 # cache_read : true