\documentclass[12pt,a4paper]{article}
\usepackage[cp1251]{inputenc}
\usepackage[bulgarian]{babel}
\usepackage[panelright,sectionbreak,screen]{pdfscreen}
\usepackage{listings}

\margins{.65in}{.65in}{.65in}{.65in}
\screensize{8.5in}{8.5in}
\definecolor{white}{rgb}{1, 1, 1}
\backgroundcolor{white}

\newcommand{\textbftt}[1]{\textbf{\texttt{#1}}}

\title{
\begin{center}
\href{http://ant.apache.org}{\imageButton{2.2in}{!}{../ant_logo_large.jpg}}
\end{center}
\vspace{2cm}Възможностите на Ant за изграждане\\ на големи проекти
\begin{center}
\small Версия V0-0-5
\end{center}
\vspace{.4cm}}
\author{Иван Иванов - \href{mailto:rambiusparkisanius@gmail.com}{rambiusparkisanius@gmail.com},\\
Петър Тахчиев - \href{mailto:paranoiabla@gmail.com}{paranoiabla@gmail.com}}

\begin{document}
\maketitle

\begin{slide}
\hypertarget{contents}{}
\tableofcontents
\end{slide}

\begin{slide}
\begin{center}
\section{Apache Ant: Уводни думи}
\begin{flushleft}
Apache Ant е инструмент за изграждане (компилиране, пакетиране, тестване) на проекти. Основните му характеристики са:
\end{flushleft}

\begin{itemize}
\item платформенa независимост - тъй като е Java-базирано приложение;
\item лесен за разширяване - много нови негови компоненти могат да се добавят, като се кодират на Java, както и на други скриптови езици като JavaScript,
Python;
\item с прост, но мощен XML синтаксис лесен за научаване;
\item може да изгражда не само Java проекти, но и такива създавани на други езици.
\end{itemize}

\end{center}

\end{slide}

\begin{slide}
\subsection{Структура на build скриптовете}
\begin{itemize}
\item Ant използва \textbftt{build файлове}, които описват как да се компилира, пакетира и тества едно приложение. Build скриптът е XML файл, съдържащ стъпките за изграждане на един проект. Големи проекти могат да се състоят от по-малки проекти всеки от които може да има отделен build скрипт. Друг главен build скрипт може да координира build процесите на подпроектите.

\item Всеки build скрипт съдържа няколко \textbftt{target}-и (цели), които могат да зависят помежду си. В повечето случаи имаме target за компилиране на проекта, target за пакетиране и target за тестване, като target-ите за тестване и пакетиране е естествено да зависят от target-a за компилиране.

\item Target-ите се състоят от \textbftt{task}-ове, които извършват някакаква операция. Например, имаме task \textbftt{<javac>}, която компилира Java файлове, както и task \textbftt{<copy>}, която копира файлове.
\end{itemize}
\end{slide}

\begin{slide}
Ето един елементарен build скрипт:
\lstset{
    basicstyle=\small,
    stringstyle=\ttfamily,
    showstringspaces=false
}
\lstinputlisting[language=Ant]{../../code/intro/build.xml}
\end{slide}

\begin{slide}
Извикваме target от този build скрипт по следния начин:
\lstset{
    basicstyle=\small\ttfamily,
    showstringspaces=false
}
\begin{lstlisting}
$ ant print-date
\end{lstlisting}
Резултатът е:
\begin{lstlisting}
Buildfile: build.xml

print-date:
     [echo] Current date is 20051006

BUILD SUCCESSFUL
Total time: 0 seconds
\end{lstlisting}
Можем да извикаме ant и без да подадем target. Тогава се вика target-а по
подразбиране, указан в \textbftt{default} аттибута на проекта:
\lstset{
    basicstyle=\small\ttfamily,
    showstringspaces=false
}
\begin{lstlisting}
$ ant
Buildfile: build.xml

print-date:
     [echo] Current date is 20051006

print-time:
     [echo] Current time is 1919

all:

BUILD SUCCESSFUL
Total time: 0 seconds
\end{lstlisting}

\end{slide}

\begin{slide}
Примерът показва:
\begin{itemize}
\item Използването на task-a \textbftt{<echo>}, който извежда някакво съобщение.
Тук част от съобщението са стойностите на \textbftt{property}-та, наречени 
\textbftt{DSTAMP}, \textbftt{TSTAMP}. Property е двойка от име и стойност, като
стойността може да се вземе чрез името с нотацията \verb+${prop_name}+; веднъж
установена, стойността на едно property не може да бъде променена;
\item Използването на task-a \textbftt{<tstamp>}, който установява стойностите
на property-та с имена \textbftt{DSTAMP}, \textbftt{TSTAMP} съответно на
текущата дата и текущото време;
\item Не е задължително task-овете да са винаги в target-и. В нашия случай task-а \textbftt{tstamp} е извън всички target-и. Тези task-ове се изълняват винаги, независимо кой target е стартиран;
\item Зависимостите на един target от други се задават чрез \textbftt{depends}
атрибута на target-а, например тarget-а \textbftt{all} зависи от 
\textbftt{print-date} и \textbftt{print-time} и те ще се изпълнят автоматично
при извикване на all;
\item Проектът може да има вложен таг \textbftt{<description>}, който описва
употребата на скрипта; \textbftt{description} атрибут може да имат и target-ите,
който описва действието им; това дава възможност за добавяне на документация на
скрипта, която по-късно може да бъде изведена с командата
\textbftt{ant -projecthelp}.
\end{itemize}
\end{slide}

\begin{slide}
Ant притежава и някои вградени property-тата, т.е. такива, които се генерират автоматично, без да е необходимо потребителят да ги дефинира. Това са:
\begin{itemize}

\item системните property-тата на JVM - същите property-ата, които достъпваме чрез метода System.getProperties();
\item специфични за Ant property-та като:
\begin{itemize}
\item \textbftt{basedir} - абсолютния път до главната директория на проекта както е указано в basedir атрибута на <project> тага;
\item \textbftt{ant.file} - абсолютния път на build скрипта, който се изпълнява в момента;
\item \textbftt{ant.version} - версията на Ant;
\item \textbftt{ant.project.name} - името на проекта, който се изпълнява в момента, както е указано в name атрибута на <project> тага;
\item \textbftt{ant.java.version} - версията на Java виртуалната машина, с която се изпълнява build скрипта.
\end{itemize}
\end{itemize}
Освен това имаме достъп до всички променливи на обкръжението, например ако искаме да вземем стойността на променлива на обкръжението наречена CATALINA\_HOME използваме следната конструкцията:
\lstset{
    basicstyle=\small,
    stringstyle=\ttfamily,
    showstringspaces=false
}
\lstinputlisting[language=Ant]{../../code/section2/env.xml}
\end{slide}

\begin{slide}
\subsection{Изграждане и тестване на HelloWorld приложение}
Следващата стъпка е да направим HelloWorld приложение, което да компилираме, тестваме и пакетираме. Приложението се състои от:
\begin{itemize}
\item Java код:

\lstset{
    basicstyle=\small,
    stringstyle=\ttfamily,
    showstringspaces=false
}
\lstinputlisting[language=Java]{../../code/HelloWorld/src/net/sourceforge/emaria/openfest/Message.java}

\lstset{
    basicstyle=\small,
    stringstyle=\ttfamily,
    showstringspaces=false
}
\lstinputlisting[language=Java]{../../code/HelloWorld/src/net/sourceforge/emaria/openfest/Main.java}
\end{itemize}
\end{slide}

\begin{slide}
\begin{itemize}
\item Кода на unit тестовете:
\lstset{
    basicstyle=\small,
    stringstyle=\ttfamily,
    showstringspaces=false
}
\lstinputlisting[language=Java]{../../code/HelloWorld/tests/src/net/sourceforge/emaria/openfest/MessageTest.java}
\end{itemize}
\end{slide}

\begin{itemize}
\begin{slide}
А ето и самия код, от build.xml-а, който:
\item компилира приложението:
\lstset{
    basicstyle=\small,
    stringstyle=\ttfamily,
    showstringspaces=false
}
\lstinputlisting[language=Ant,firstline=29,lastline=35]{../../code/HelloWorld/build.xml}
\item компилира тестовете:
\lstset{
    basicstyle=\small,
    stringstyle=\ttfamily,
    showstringspaces=false
}
\lstinputlisting[language=Ant,firstline=87,lastline=94]{../../code/HelloWorld/build.xml}
\end{slide}

\begin{slide}
\item стартира тестовете:
\lstset{
    basicstyle=\small,
    stringstyle=\ttfamily,
    showstringspaces=false
}
\lstinputlisting[language=Ant,firstline=96,lastline=121]{../../code/HelloWorld/build.xml}
\end{slide}
\end{itemize}

\begin{slide}
Тези примери демонстрират:
\begin{itemize}
\item Task-а \textbftt{<junit>}, който изпълнява всички unit тестове, избрани чрез вложеният елемент \textbftt{<batchtest>};
\item Елемента \textbftt{formatter}, който трансформира резултата от тестовете във формата указан от атрибута му \textbftt{type};
\item Атрибутите \textbftt{haltonerror}, \textbftt{haltonfailure}, които указват дали изпълнението на build-а да бъде прекратено, ако тестовете не са успешни;
\item Атрибутите \textbftt{failureproperty} и \textbftt{errorproperty}, указващи имената на property-тата, които се установяват ако тестовете не са успешни;
\item Task-а \textbftt{<junitreport>}, който преобразува резултатите от тестовете от XML формат в HTML формат чрез XSLT трансформация;
\item Task-а \textbftt{<fail>}, който прекратява build-a като неуспешен ако някакво условие е изпълнено;
\item В нашия пример указваме build-а да не спира при неуспех на тестовете, но задаваме при  евентуален неуспех да се инициализира property-то \textbftt{test.error}, което ни послужи ръчно да спрем build-а като неуспешен, но едва след като сме генерирали HTML резултатите с <junitreport>.
\end{itemize}
\end{slide}

\begin{enumerate}
\begin{slide}
\subsection{Първа употреба на \textbftt{<presetdef>}}
Task-ът \textbftt{<presetdef>} създава нова дефиниция на вече съществуващ
task, като предефинира с фиксирани стойности някои от атрибути или елементи й.
Ето един възможен сценарий за употреба на <presetdef>:
\item Task-а <javac> по подразбиране не генерира debug информация, която по
време на разработка е необходимa за проследяване на грешки; както видяхме в
HelloWorld приложението <javac> се използва поне два пъти в build скрипта:
за компилиране на приложението и за компилирането на unit тестовете;
\item Можем всеки път, когато използваме <javac>, да цитираме едни и същи
стойности на атрибутите \textbftt{debug}, \textbftt{debuglevel} и
\textbftt{deprecation}, но това води до буквално повтаряне на код;
\item Решението е да използваме <presetdef>:
\begin{lstlisting}[language=Ant,basicstyle=\small,stringstyle=\ttfamily]
<presetdef name="javac">
    <javac debug="on" debuglevel="vars,lines,source"
        deprecation="on"/>
</presetdef>
\end{lstlisting}
Така всеки път когато използваме <javac>, използваме горната предефинирана
версия;
\item Това води и до следния проблем: debug информацията увеличава размера
на компилираните класове, което не е желано за официални build-ове, а всяко
ползване на <javac> генерира такава информация;
\end{slide}

\begin{slide}
\item Решението е вместо фиксирани стойности за атрибутите да изпозваме
<property>-та. Тъй като стойностите им не могат да се променят, всичко което
трябва да осигурим, е при правене на официални build-ове, стойностите на 
debug property-тата да се установяват на off преди всичко друго.
\item В нашия случай това постигаме с добавянето на target-а
\lstset{
    basicstyle=\small,
    stringstyle=\ttfamily,
    showstringspaces=false
}
\lstinputlisting[language=Ant,firstline=130,lastline=134]{../../code/HelloWorld/build.xml}
и указваме target-а за създаване на официална дистрибуция \textbftt{dist} да
зависи от \textbftt{-dist.init}:
\lstset{
    basicstyle=\small,
    stringstyle=\ttfamily,
    showstringspaces=false
}
\lstinputlisting[language=Ant,firstline=141,lastline=143]{../../code/HelloWorld/build.xml}
\end{slide}
\end{enumerate}

\begin{slide}
\section{Описание на task-овете \textbftt{<subant>}, \textbftt{<import>},
\textbftt{<macrodef>}}
Тези task-ове, както и <presetdef> се въведоха в Ant 1.6, за да улеснят
създаването на нови task-ове, без да е необходимо да се пише кода на Java,
за опростяването на build процеса при големи проекти и за повторната
употреба на съществуващи build скриптове.
\end{slide}

\begin{slide}
\subsection{Дефиниране на нови task-ове чрез \textbftt{<macrodef>}}
Task-ът \textbftt{<macrodef>} дефинира нови task-ове, като входните данни на
тези нови task-ове задаваме с елементите \textbftt{<attribute>} и 
\textbftt{<element>}.\\
Ето един полезен <macrodef>, който отваря зададен HTML файл в браузъра,
по подразбиране използвайки Linux-ката команда \textbftt{htmlview}:
\lstset{
    basicstyle=\small,
    stringstyle=\ttfamily,
    showstringspaces=false
}
\lstinputlisting[language=Ant,firstline=27,lastline=34]{../../code/section2/macrodef/browser.macrodef}
Той се използва като всички останали task-ове:
\lstset{
    basicstyle=\small,
    stringstyle=\ttfamily,
    showstringspaces=false
}
\lstinputlisting[language=Ant,firstline=39,lastline=42]{../../code/section2/macrodef/browser.macrodef}
Можем да напишем и версия на този <macrodef>, която да работи под Windows:
\lstinputlisting[language=Ant,firstline=15,lastline=23]{../../code/section2/macrodef/browser.macrodef}
\end{slide}

\begin{slide}
Тези две версии могат да се комбинират в един и същи build скрипт,
така че <browse> task-а да работи и под Windows, и под Linux:
\lstset{
    basicstyle=\small,
    stringstyle=\ttfamily,
    showstringspaces=false
}
\lstinputlisting[language=Ant,firstline=4,lastline=37]{../../code/section2/macrodef/browser.macrodef}
\end{slide}

\begin{slide}
\subsection{Повторна употреба на build скриптове чрез \textbftt{<import>}}
В горния пример видяхме, че след извикването на target-а \textbftt{browserDef}
macrodef-ът <browse> се дефинира за съответната операционна система.
Естествено е да поискаме да използваме този <macrodef> и в други build
скриптове.\\
Един от начините за повторна употреба на Ant build скриптове (или части 
от тях) е чрез XML entity-та, като този начин не е свързан с Ant, а с XML
формата на build скриптовете.\\
Другият начин е да използваме task-а \textbftt{<import>}. Пример за синтаксиса
на този task е:
\lstset{
    basicstyle=\small,
    stringstyle=\ttfamily,
    showstringspaces=false
}
\begin{lstlisting}[language=Ant]
<import file="imported.xml" optional="true"/>,
\end{lstlisting}
където атрибутът \textbftt{file} указва друг build файл, който искаме да
включим в настоящия build скрипт, а атрибутът \textbftt{optional} указва дали
build-ът да спре, ако импортваният build файл не съществува.
\end{slide}

\begin{slide}
Build скриптът, съдържащ macrodef-а <browse>, се импортва по следния начин:
\lstset{
    basicstyle=\small,
    stringstyle=\ttfamily,
    showstringspaces=false
}
\lstinputlisting[language=Ant]{../../code/section2/import/build.xml}
Target-ът test-browser зависи от target-а browserDef (който е дефиниран в
импортвания файл), тъй като macrodef-ът <browse> се създава след като се
изпълни target-а browserDef. Така <import> позволява повторното ползване
и на macrodef-ове и на target-и.\\
В основата си той работи както работят XML entity-та, т.е. <import> добавя
в импортващият файл всичко от импортвания без <project> тага. Разликите
обаче са, че <import> въвежда предефиниране на target-и и някои специални
property-та.
\end{slide}

\begin{slide}
\subsection{Стартиране на няколко build скрипта чрез \textbftt{<subant>}}
Да разгледаме следната ситуация: нека имаме даден продукт, който се състои
от няколко проекта, и изграждането на продукта изисква изграждането на
тези проекти. В повечето случаи всеки от проектите има свой собствен
build скрипт и като build скриптът на продукта вика build скриптовете на
проектите.\\
В древността преди Ant 1.6 това се постига с task-а \textbftt{<ant>}. Ето псевдокод, който илюстрира тази идея:
\lstset{
    basicstyle=\small,
    stringstyle=\ttfamily,
    showstringspaces=false
}
\begin{lstlisting}[language=Ant]
<target name="compile-product">
    <ant target="compile" antfile="project1/build.xml"/>
    <ant target="compile" antfile="project2/build.xml"/>
    ...
    <ant target="compile" antfile="projectN/build.xml"/>
</target>
\end{lstlisting}
Един удобен заместител на task-а <ant> е task-а <subant>, който изглежда по
следния начин:
\lstset{
    basicstyle=\small,
    stringstyle=\ttfamily,
    showstringspaces=false
}
\begin{lstlisting}[language=Ant]
<target name="compile-product">
    <subant target="compile">
        <dirset dir="${basedir}">
            <include name="project*"/>    
        </dirset>
    </subant>
</target>
\end{lstlisting}
\end{slide}

\begin{slide}
\section{Демонстрация на проект използващ \textbftt{<subant>},
\textbftt{<import>} и \textbftt{<macrodef>}}
Проектът, чрез който ще илюстрираме горните идеи, се нарича \textbftt{antutils}. Той реализира няколко разширения на Apache Ant, отделени в компоненти, които са:
\begin{itemize}
\item FileInfo - Ant task, който извлича информация за даден файл, като размер, дали е скрит и т.н;
\item JazzyTask - Ant task, който проверява правописа на файлове, използвайки Java библиотеката Jazzy;
\item Input - този компонент позволява маскирането на пароли, въвеждани през текстова консола;
\item MailAttachLogger - Ant listener, който наследява оригиналния MailLogger и дава възможност за прикачване на файлове към съобщението с резултатите от build процеса.
\end{itemize}

\end{slide}

\begin{slide}
Всеки от тези компоненти трябва да се компилира, тества и пакетира. Тези три операции могат да се отделят в един общ build скрипт - \textbftt{common.xml}, който чрез <import> да се използва в build скрипта на всеки компонент. При необходимост build скрипта на даден компонент може да предефинира някое property или task от common.xml. Имаме и един главен build скрипт \textbftt{build.xml}, който използва <subant>, за да извика build скриптовете на компонентите.

Примерът с antutils показва случая, при който компонентите са независими един от друг. Същата техника обаче с някои изменения може да се използва и при изграждане на проекти, които зависят един от друг.
\end{slide}

\begin{slide}
\section{Достъп до настоящата презентация и примерния код}
Можете да свалите презентацията под формата на архив наречен \textbftt{OFP2005.tar.bz2} от адреса\\ \small\url{http://sourceforge.net/project/showfiles.php?group_id=103509}
\normalsize

Последната й версия може да се изтегли от CVS хранилището на SF.net чрез командите:
\lstset{
    basicstyle=\small,
    stringstyle=\ttfamily,
    showstringspaces=false
}
\begin{lstlisting}[language=bash]
cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/emaria login
cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/emaria co -P \
OFP2005 
\end{lstlisting}

Кодът на проекта \textbftt{antutils} можете да свалите пак от CVS хранилището на SF.net чрез командите:
\lstset{
    basicstyle=\small,
    stringstyle=\ttfamily,
    showstringspaces=false
}
\begin{lstlisting}[language=bash]
cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/emaria login
cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/emaria co -P
antutils
\end{lstlisting}

При поискване на парола за CVS сървъра, дайте празна такава, т.е. просто натиснете Enter.
\end{slide}

\end{document}
