<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	>

<channel>
	<title>Blog ITPlace</title>
	<atom:link href="http://blog.itplace.cz/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.itplace.cz</link>
	<description>ITPlace - firemní blog</description>
	<pubDate>Tue, 23 Feb 2010 19:48:56 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Datové schránky - první zpráva</title>
		<link>http://blog.itplace.cz/datove-schranky-prvni-zprava/</link>
		<comments>http://blog.itplace.cz/datove-schranky-prvni-zprava/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 19:48:27 +0000</pubDate>
		<dc:creator>Jan Šmuk</dc:creator>
		
		<category><![CDATA[Internet obecně]]></category>

		<guid isPermaLink="false">http://blog.itplace.cz/?p=285</guid>
		<description><![CDATA[
<p>Minulý týden, jsme se stěhovali do nových prostor ve Strašnicích. Mimo
jiné bylo třeba nahlásit na všemožných úřadech změnu naší
korespondenční adresy. V případě finančního úřadu bylo možné změnu
nahlásit pomocí Datových schránek. V tomto článku se chci podělit
o svoji první zkušenost s použitím služby Datových schránek.</p>

<p>Přihlášení do Datových schránek proběhlo bez větších problémů.
Chvíli mi trvalo najít stránku s formulářem pro přihlášení, čekal
bych […]</p>

<!-- by Texy2! -->]]></description>
			<content:encoded><![CDATA[
<p>Minulý týden, jsme se stěhovali do nových prostor ve Strašnicích. Mimo
jiné bylo třeba nahlásit na všemožných úřadech změnu naší
korespondenční adresy. V případě finančního úřadu bylo možné změnu
nahlásit pomocí Datových schránek. V tomto článku se chci podělit
o svoji první zkušenost s použitím služby Datových schránek.</p>

<p>Přihlášení do Datových schránek proběhlo bez větších problémů.
Chvíli mi trvalo najít stránku s formulářem pro přihlášení, čekal
bych do očí bijící odkaz někde na oficiálních informačních stránkách
Datových schránek <a
href="http://www.datoveschranky.info">www.datoveschranky.info</a>. Dalším
drobným zádrhelem byla instalace kořenových certifikátů Postsignum.
Nakonec jsem našel potřebné certifikáty zde: <a
href="http://vca.postsignum.cz/www/authorities.php">http://vca.postsignum.cz/…horities.php</a>.</p>

<p>Po přihlášení bylo poměrně jasné, co dál. Stisknul jsem tlačítko
Nová zpráva. V prvním kroku jsem byl požádán o vyplnění, komu chci
zprávu poslat. Formulář pro vyhledávání příjemců se ale choval dost
zvláštně. Potřeboval jsem zprávu poslat na Finanční úřad
v Jindřichově Hradci. Zkusil jsem tedy nejprve zadat do políčka Název
organizace výraz „financni urad“. Výsledkem bylo toto:</p>

<div style="text-align:center" class="figure"><img
src="/wp-content/uploads/ds-nic-nenalezeno.png"
alt="„financni urad“: nic nenalezeno" />
	<p>„financni urad“: nic nenalezeno</p>
</div>

<p>Nic nebylo nalezeno. Mým druhým pokusem bylo použít diakritiku, tedy
„finanční úřad“:</p>

<div style="text-align:center" class="figure"><img
src="/wp-content/uploads/ds-priliz-mnoho-vysledku.png"
alt="„finanční úřad“: příliž mnoho výsledků" />
	<p>„finanční úřad“: příliž mnoho výsledků</p>
</div>

<p>Hmm, tady mi svitla naděje, ale stále žádný výsledek. Zkusil jsem tedy
přednější výraz „finanční úřad jindřichův hradec“ a … zase nic.
Posledním pokusem bylo vyplnění „finanční úřad“ do políčka Název
organizace a „jindřichův hradec“ do políčka Obec. Stále bez výsledku.
Nakonec jsem se uchýlil k vyhledání IČO finančního úřadu na jiných
stránkách a poté vyhledání příjemce podle IČO.</p>

<p>Samotnou zprávu nenapíšete bez nainstalování pluginu 602 XML Filler.
602 XML Filler je nástroj pro vyplňování elektronických formulářů,
proč ale nestačí obyčejný HTML formulář?</p>

<div style="text-align:center" class="figure"><img
src="/wp-content/uploads/ds-nova-zprava.png" alt="Nová zpráva" />
	<p>Nová zpráva</p>
</div>

<p>Finančnímu úřadu jsem potřeboval sdělit naši novou korespondenční
adresu. Ve formuláři ale úplně chyběla možnost přímo zadat text zprávy.
Po několika minutách zkoumání jsem musel zprávu napsat ve Wordu a tento
dokument přiložit k datové zprávě.</p>

<p>Psaní zprávy mi trvalo bez mála hodinu. Jaké jsou vaše zkušenosti?</p>

<!-- by Texy2! -->]]></content:encoded>
			<wfw:commentRss>http://blog.itplace.cz/datove-schranky-prvni-zprava/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Facebook Connect - připojte se, prosím</title>
		<link>http://blog.itplace.cz/facebook-connect-pripojte-se-prosim/</link>
		<comments>http://blog.itplace.cz/facebook-connect-pripojte-se-prosim/#comments</comments>
		<pubDate>Sun, 24 Jan 2010 17:46:55 +0000</pubDate>
		<dc:creator>Jan Šmuk</dc:creator>
		
		<category><![CDATA[Facebook]]></category>

		<category><![CDATA[php]]></category>

		<category><![CDATA[Přidat nový štítek]]></category>

		<guid isPermaLink="false">http://blog.itplace.cz/?p=273</guid>
		<description><![CDATA[
<p>Podle statistik již téměř 2 miliony čechů má svůj účet na
Facebooku. Je tedy logické, že se na Facebook soustředí pozornost více a
více společností, které se snaží tohoto ohromného počtu uživatelů
využít. Díky skvělému programovému rozhraní lze Facebook integrovat
s firemními weby nebo e-shopy. Integrace s Facebookem vám umožní např.
zobrazovat obsah Facebooku na vašich stránkách nebo naopak, publikovat na
Facebooku váš obsah […]</p>

<!-- by Texy2! -->]]></description>
			<content:encoded><![CDATA[
<p>Podle statistik již téměř 2 miliony čechů má svůj účet na
Facebooku. Je tedy logické, že se na Facebook soustředí pozornost více a
více společností, které se snaží tohoto ohromného počtu uživatelů
využít. Díky skvělému programovému rozhraní lze Facebook integrovat
s firemními weby nebo e-shopy. Integrace s Facebookem vám umožní např.
zobrazovat obsah Facebooku na vašich stránkách nebo naopak, publikovat na
Facebooku váš obsah a přilákat tím vaše potenciální zákazníky.
V ItPlace jsme integrovali e-shop <a
href="http://www.cockovnik.cz">www.cockovnik.cz</a> s Facebookem a rádi se
o své zkušenosti podělíme.</p>

<p>V tomto článku si ukážeme, jak umožnit vašim uživatelům přihlásit
se do vaší webové aplikace pomocí Facebook Connect.</p>

<p>Cílem je vytvořit stránku na web serveru běžícím na vašem
počítači, která bude obsahovat tlačítko pro přihlášení pomocí
Facebooku. Po stisknutí tlačítka budete požádáni o přihlášení na
Facebook (pokud zrovna nejste přihlášení) a po úspěšném přihlášení
na stránce zobrazíme, kdo je přihlášen.</p>

<h3>Vytvoření Facebook aplikace</h3>

<p>Aby mohly vaše stránky komunikovat s Facebookem, musíte nejprve na
stránkách Facebooku vytvořit Facebook aplikaci. K tomu si musíte do svého
účtu nainstalovat aplikaci Vývojář, která slouží k administraci vašich
Facebook aplikací.</p>

<p>Aplikaci vývojář nainstalujete klepnutím na tento odkaz: <a
target="_blank"
href="http://www.facebook.com/developers">http://www.facebook.com/developers</a>.
Po přihlášení budete požádáni o povolení přístupu aplikace Vývojář
k vašemu účtu. Klikněte na tlačítko „Povolit“.</p>

<p>Aplikace Vývojář vypadá takto:</p>

<div style="text-align:center" class="figure"><img
src="/wp-content/uploads/vyvojar.png" alt="Aplikace Vývojář" />
	<p>Aplikace Vývojář</p>
</div>

<p>Stránka obsahuje mimo jiné seznam vašich Facebook aplikací a tlačítko
pro vytvoření nové aplikace. Nyní klikněte na „Vytvoření nové
aplikace“.</p>

<div style="text-align:center" class="figure"><img
src="/wp-content/uploads/screenshot_002.png" alt="Nová aplikace" />
	<p>Nová aplikace</p>
</div>

<p>Stačí zvolit vhodné jméno pro aplikaci, souhlasit s podmínkami a
stisknout „Vytvoření aplikace“. Pokud vše proběhlo správně, jste nyní
v administraci vaší Facebook aplikace. Zkopírujte si API klíč a API
secret, pomocí těchto údajů se budou všechna volání Facebook API
z vašich stránek identifikovat.</p>

<h3>Příprava testovací stránky</h3>

<p>Facebook API je založené na REST webových službách, nezáleží tedy na
platformě ani použitém programovacím jazyce. Vytvoření dotazu na Facebook
API a zpracování výsledku volání lze dělat manuálně, ale vývojáři
Facebooku poskytují také velmi šikovné knihovny v několika jazycích.
V tomto článku použijeme jazyk PHP a příslušnou knihovnu.</p>

<p>Zde: <a
href="http://svn.facebook.com/svnroot/platform/clients/packages/facebook-platform.tar.gz">http://svn.facebook.com/…tform.tar.gz</a>
si stáhněte knihovnu pro práci s Facebook API v PHP. Z archívu rozbalte
adresář php do adresáře &lt;APPROOT&gt;/facebook-client, kde &lt;APPROOT&gt;
je kořenový adresář vaší testovací web aplikace.</p>

<p>V našem testu budeme používat Facebook javascript knihovnu, která
komunikuje s Facebookem formou AJAX volání. Internetové prohlížeče
zakazují komunikaci mezi různými doménami. Naštěstí existuje způsob, jak
tento zákaz obejít. Vytvořte soubor &lt;APPROOT&gt;/xd_re­ceiver.htm
s následujícím obsahem:</p>

<pre>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" &gt;
&lt;head&gt;
  &lt;title&gt;Cross-Domain Receiver Page&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;script
src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/XdCommReceiver.js?2" type="text/javascript"&gt;&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>

<p>Facebook aplikace musí vědět, kde jsou vaše stránky umístěny. Toto
nastavení najdete v administraci Facebook aplikace v záložce Připojit. Do
políčka Connect URL vepište kořenovou adresu vašich stránek.
Například:</p>

<div style="text-align:center" class="figure"><img
src="/wp-content/uploads/screenshot_003.png" alt="Umístění stránek" />
	<p>Umístění stránek</p>
</div>

<p>V tomto případě je tedy soubor xd_receiver.htm přístupný na adrese:
http//localhost/fb-test/xd_recei­ver.htm.</p>

<p>Vytvořte soubor &lt;APPROOT&gt;/login.php s následujícím obsahem:</p>

<pre>&lt;?php
$apiKey = .... vaše API key;
$apiSecret = .... vaše API secret;
?&gt;
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" &gt;
&lt;head&gt;
  &lt;title&gt;Login&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;script
src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php/cs_CZ" type="text/javascript"&gt;&lt;/script&gt;
&lt;script&gt;
        function facebookUserLoggedIn() {
                alert('OK!');
        }
&lt;/script&gt;

&lt;p&gt;
  &lt;a href="#" onclick="FB.Connect.requireSession(facebookUserLoggedIn); return false;" &gt;
     &lt;img id="fb_login_image" src="http://wiki.developers.facebook.com/images/f/f5/Connect_white_large_long.gif" /&gt;
  &lt;/a&gt;
&lt;/p&gt;

&lt;script type="text/javascript"&gt;
FB_RequireFeatures(["XFBML"], function() {
        FB.Facebook.init("&lt;?=$apiKey?&gt;", "xd_receiver.htm");
});
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>

<p>V tomto kódu jsou tyto důležité části:</p>

<ol>
	<li>konfigurace apiKey a apiSecret,</li>

	<li>načtení javascriptové knihovny,</li>

	<li>call-back funkce facebookUserLog­gedIn(), která se automaticky zavolá po
	úspěšném přihlášení na Facebook.</li>

	<li>Tlačítko pro přihlášení pomocí Facebooku. Všimněte si parametru
	volání funkce FB.Connect.re­quireSession(fa­cebookUserLog­gedIn). Ano,
	facebookUserLog­gedIn je reference na call-back funkci.</li>

	<li>Inicializace javascriptového Facebook klienta.</li>
</ol>

<p>Struktura vaší aplikace je tedy:</p>

<pre>&lt;APPROOT&gt;
   |- facebook-client
   |    |- json-wrapper
   |    |    |- .....
   |    |- facebook.php
   |    |- facebook_mobile.php
   |    |- facebookapi_php5_restlib.php
   |- xd_receiver.htm
   |- login.php</pre>

<p>Nyní jsme připraveni na první test! V prohlížeči zadejte adresu: <a
href="http://localhost/fb-test/login.php:http://localhost/fbtest/login.php">http://localhost/…st/login.php</a>.
Zobrazí se prázdná stránka s tradičním modrým tlačítkem „Facebook
Connect“. Po stisknutí tlačítka se otevře pop-up okno s výzvou pro
přihlášení do Facebooku. Po úspěšném přihlášení se zobrazí
javascriptová hláška „OK!“.</p>

<h3>Kdo tam?</h3>

<p>Funguje to, ale jak zjistit, kdo se to vlastně přihlásil? K tomu nám
poslouží PHP knihovna pro práci s Facebookem. Upravte soubor
&lt;APPROOT&gt;/login.php tímto způsobem:</p>

<pre>&lt;?php
$apiKey = .... vaše API key;
$apiSecret = .... vaše API secret;

include_once "facebook_client/facebook.php";

$fb = new Facebook($apiKey, $apiSecret);
$fbUserId = $fb-&gt;user;

if($fbUserId != null) {
  echo "prihlaseny uzivatel: $fbUserId&lt;br/&gt;";
}
?&gt;
...</pre>

<p>Pokud není přihlášen žádný Facebook uživatel, má proměnná
$fbUserId hodnotu null. Pokud je někdo přihlášen, je v proměnné $fbUserId
identifikátor Facebook uživatele.</p>

<p>Toto ID lze použít pro spárování uživatele ve vaší databázi
s Facebook uživatelem. Po přihlášení pomocí Facebook Connect se
podíváme, zda v naší databázi existuje uživatel s tímto Facebook ID.
Pokud ano, pak uživatele přihlásíme. Pokud ne, uživatele zaregistrujeme a
přihlásíme.</p>

<p>Je také snadné změnit chování stránky login.php pro případ, že je
uživatel již přihlášen. Například už nemusíme zobrazovat tlačítko pro
přihlášení.</p>

<p>Ještě upravíme call-back funkci tak, aby se stránka automaticky po
přihlášení aktualizovala:</p>

<pre>...
&lt;script&gt;
        function facebookUserLoggedIn() {
                window.location='/fb-test/login.php';
        }
&lt;/script&gt;
...</pre>

<h3>Závěr</h3>

<p>Ukázali jsme si na jednoduchém příkladě, začít integrovat váš web
s Facebookem a použít Facebook pro přihlašování uživatelů. O dalších
možnostech Facebook API, jako jsou</p>

<ul>
	<li>zjištění informací o uživatelích,</li>

	<li>poslání příspěvků na zeď uživatele,</li>

	<li>vytvoření fotoalba a vložení fotografie a</li>

	<li>použití komentářů,</li>
</ul>

<p>se budete moci dočíst v dalších článcích na našem blogu.</p>

<h3>Odkazy</h3>

<ul>
	<li><a
	href="http://wiki.developers.facebook.com/index.php/Main_Page">http://wiki.developers.facebook.com/…hp/Main_Page</a> –
	dokumentace Facebook platformy.</li>

	<li><a
	href="http://wiki.developers.facebook.com/index.php/Facebook_Connect_Tutorial1">http://wiki.developers.facebook.com/…ct_Tutorial1</a> –
	pěkný tutoriál.</li>

	<li><a href="http://www.cockovnik.cz/">http://www.cockovnik.cz/</a> –
	Čočkovník, který jsme integrovali s Facebookem.</li>
</ul>

<!-- by Texy2! -->]]></content:encoded>
			<wfw:commentRss>http://blog.itplace.cz/facebook-connect-pripojte-se-prosim/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Tomcat - Sdílený back-end</title>
		<link>http://blog.itplace.cz/tomcat-sdileny-backend/</link>
		<comments>http://blog.itplace.cz/tomcat-sdileny-backend/#comments</comments>
		<pubDate>Mon, 17 Aug 2009 05:21:56 +0000</pubDate>
		<dc:creator>Jan Šmuk</dc:creator>
		
		<category><![CDATA[Nezařazené]]></category>

		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://blog.itplace.cz/?p=177</guid>
		<description><![CDATA[
<p>Téměř všechny příklady a tutoriály, jak konfigurovat Tomcat popisují
jen ty nejjednodušší případy a aplikace. My jsme potřebovali Tomcat
nakonfigurovat tak, aby několik web aplikací mohlo sdílet jediný modul
obsahující servisní a DAO vrstvy. V tomto článku vám ukážu,
jak na to.</p>

<p>Struktura naší aplikace</p>

<p>Deployment diagram</p>

<p>Front-end je tvořen několika webovými aplikacemi. V našem případě
jsme měli pro každý výstupní formát speciální web aplikaci
(WML, […]</p>

<!-- by Texy2! -->]]></description>
			<content:encoded><![CDATA[
<p>Téměř všechny příklady a tutoriály, jak konfigurovat Tomcat popisují
jen ty nejjednodušší případy a aplikace. My jsme potřebovali Tomcat
nakonfigurovat tak, aby několik web aplikací mohlo sdílet jediný modul
obsahující servisní a DAO vrstvy. V tomto článku vám ukážu, jak
na to.</p>

<h3>Struktura naší aplikace</h3>

<div style="text-align:center" class="figure"><img
src="/wp-content/uploads/deployment1.png" alt="Deployment diagram" />
	<p>Deployment diagram</p>
</div>

<p>Front-end je tvořen několika webovými aplikacemi. V našem případě
jsme měli pro každý výstupní formát speciální web aplikaci (WML, HTML).
Tyto aplikace sdílí společný back-end, který obsahuje Spring application
context a v něm nakonfigurovanou servisní a DAO vrstvu. Service locator pouze
zabaluje Spring application context a webové aplikace si jej mohou najít
v JNDI.</p>

<p>Proč je výhodou mít jediný společný back-end? V našem případě
back-end obsahuje většinu business logiky, která je všem web aplikacím
společná. Jedná se například o persistenci, cache, scheduler, logování
statistik, atd. Další výhodou je, že můžete modifikovat web aplikaci bez
nutnosti restartování back-endu, což se při vývoji hodí, protože back-end
může startovat dost dlouho (v jednom z našich projektů back-end startoval
půl minuty).</p>

<h3>Testovací aplikace</h3>

<p>Připravil jsem archív obsahující testovací aplikaci, skládající se
z front-endu, back-endu a konfigurace tomcatu. Stáhněte si <a
href="http://blog.itplace.cz/wp-content/uploads/tomcat-example.zip">tomcat-example.zip</a>
a rozbalte někam na disk. Abyste mohli tuto aplikaci zkompilovat a spustit,
musíte mít následující:</p>

<ul>
	<li>JDK 1.5 a výše – <a
	href="http://java.sun.com/javase/downloads/index.jsp">http://java.sun.com/…ds/index.jsp</a></li>

	<li>Tomcat 6 – Stahněte si Tomcat z <a
	href="http://tomcat.apache.org/download-60.cgi">http://tomcat.apache.org/download-60.cgi</a>.
	Pro naše účely není třeba instalovat, stačí někam rozbalit. Je
	užitečné nastavit si systémovou proměnnou TOMCAT_HOME na adresář, kde
	Tomcat máte.</li>

	<li>Apache Ant – <a
	href="http://ant.apache.org/bindownload.cgi">http://ant.apache.org/bindownload.cgi</a></li>
</ul>

<p>Po rozbalení archívu tomcat-example.zip byste měli mít na disku tuto
strukturu:</p>

<pre>───tomcat-example
   │   build.xml
   │
   ├───core
   │   │   .classpath
   │   │   .project
   │   │
   │   └───src
   │       └───itplace
   │           └───example
   │               └───core
   │                       HelloService.java
   │                       HelloServiceImpl.java
   │                       ServiceLocator.java
   │                       ServiceLocatorFactory.java
   │                       ServiceLocatorImpl.java
   │
   ├───tomcat
   │   │   run.cmd
   │   │
   │   └───conf
   │           catalina.policy
   │           catalina.properties
   │           context.xml
   │           logging.properties
   │           server.xml
   │           tomcat-users.xml
   │           web.xml
   │
   └───webapp1
       │   .classpath
       │   .project
       │
       ├───src
       │   └───itplace
       │       └───example
       │           └───webapp1
       │                   HelloServlet.java
       │
       └───webapp
           └───WEB-INF
               │   web.xml
               │
               └───classes</pre>

<ul>
	<li>tomcat-example/core obsahuje třídy back-endu</li>

	<li>tomcat-example/webapp1 je projekt obsahující web aplikaci.</li>

	<li>tomcat-exmple/tomcat obsahuje konfiguraci Tomcatu a dávku run.cmd, která
	nastartuje nakonfigurovaný tomcat.</li>
</ul>

<p>Spuštěním příkazu ant v adresáři tomcat-example dojde ke
zkompilování obou projektů core a webapp1. Výsledek kompilace se uloží do
tomcat-example/core/bin resp.
tomcat-example/webap­p1/webapp/WEB-INF/classes.</p>

<p>Projekty core a webapp1 si můžete naimportovat do Eclipse, budete ale
potřebovat říct Eclipse, kde má hledat knihovny serveru Tomcat.</p>

<h3>Konfigurace Tomcatu</h3>

<p>Nejprve prozkoumáme adresář tomcat-example/tomcat. Tento adresář
neobsahuje instalaci Tomcatu ale pouze jeho konfiguraci. Pro spuštění naší
aplikace je potřeba:</p>

<h4>Nakonfigurovat classpath společnou všem aplikacím (common loader)</h4>

<p>Podívejte se do souboru tomcat-example/tomcat/con­f/catalina.pro­perties.
Na konci řádku 47 najdete toto:</p>

<pre>common.loader= ...... ${catalina.base}/../core/bin</pre>

<p>Proměnná ${catalina.base} je nastavená do adresáře
tomcat-example/tomcat. Tomcat tedy do classpath společné všem web aplikacím
i serveru samotného přidá třídy našeho back-endu.</p>

<h4>Nakonfigurovat ServiceLocator</h4>

<p>Třídu <code>ServiceLocatorImpl</code> mužete najít v projektu
tomcat-example/core:</p>

<pre>package itplace.example.core;

public class ServiceLocatorImpl implements ServiceLocator {
    public HelloService getHelloService() {
        return new HelloServiceImpl();
    }
}</pre>

<p>Vidíte, že tato implementace pouze vytváří novou instanci service
HelloServiceImpl. Na tomto místě v reálném projektu může být použit
například Spring a jeho BeanFactory.</p>

<p>Jak tedy přinutit Tomcat, aby při startu vytvořil jedinou instanci třídy
ServiceLocatorImpl? Podívejte se do souboru
tomcat-example/tomcat/con­f/server.xml. Na řádku 40 najdete tento
kousek xml:</p>

<pre>&lt;Resource name="serviceLocator" auth="Container"
      type="itplace.example.core.ServiceLocator"
      description=""
      factory="itplace.example.core.ServiceLocatorFactory"
/&gt;</pre>

<p>Pomocí tagu Resource deklarujeme JNDI resource typu
<code>itplace.example.core.ServiceLocator</code> a jména
<code>serviceLocator</code>. Tomcat pro jeho vytvoření použije továrnu
<code>itplace.example.core.ServiceLocatorFactory</code>, která
vypadá takto:</p>

<pre>package itplace.example.core;

import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;

public class ServiceLocatorFactory implements ObjectFactory {

    @Override
    public Object getObjectInstance(Object obj, Name name, Context nameCtx,
            Hashtable&lt;?, ?&gt; environment) throws Exception {
        System.out.println("creating new service locator");
        return new ServiceLocatorImpl();
    }
}</pre>

<p>Vidíte, že tovární metoda <code>getObjectInstance</code> jednoduše
vytváří novou instanci třídy <code>ServiceLocatorImpl</code>.</p>

<h4>Zpřístupnit ServiceLocator webovým aplikacím</h4>

<p>Tomcat již tedy inicializuje náš service locator při startu. Nyní je
potřeba říct, jak k němu webové aplikace mohou přistupovat. Tuto
konfiguraci najdete v souboru tomcat-example/tomcat/con­f/context.xml na
řádku 36:</p>

<pre>&lt;ResourceLink name="serviceLocator" global="serviceLocator"
    type="itplace.example.core.ServiceLocator" /&gt;</pre>

<p>Tento kousek xml, již jen propojuje globální kontext serveru s kontextem
webových aplikací. Nyní mohou web aplikace získat referenci na náš
ServiceLocator standardním vyhledáním v JNDI. Podívejte se, jak toto
vyhledání funguje v servletu HelloServlet, který najdete v projektu
tomcat-example/webapp1:</p>

<pre>....
Context initialContext;
try {
    initialContext = new InitialContext();
    ServiceLocator serviceLocator =
        (ServiceLocator) initialContext.lookup("java:comp/env/serviceLocator");
    PrintWriter out = response.getWriter();
    String message =
        serviceLocator.getHelloService().getHelloMessage("ITPlace");
    out.println("HelloServlet: " + message);
} catch (NamingException e) {
    throw new ServletException(e);
}
....</pre>

<p>Referenci na náš service locator získáme vyhledáním
<code>java:comp/env/serviceLocator</code> v JNDI. Tuto část je pak dobré
přesunout do některé statické metody, aby jste nemuseli tento kód opakovat
v každém servletu.</p>

<h3>Spuštění naší aplikace</h3>

<p>To je celá věda, nyní můžete aplikaci spustit:</p>

<ul>
	<li>nejprve vše zkompilujte – v adresáři tomcat-example spusťte příkaz
	<code>ant</code>.</li>

	<li>v adresáři tomcat-example/tomcat spusťte dávku
	<code>run.cmd</code>.</li>

	<li>otevřete svůj internetový prohlížeč a jděte na: <a
	href="http://localhost:8080/webapp1/HelloServlet">http://localhost/…HelloServlet</a></li>
</ul>

<p>Pokud vše proběhlo správně, měli byste vidět hlášku:
<code>HelloServlet: HelloServiceImpl says: hello ITPlace !!!</code>.</p>

<h3>Závěr</h3>

<p>Ikdyž je Tomcat pouze servlet container, dají se s ním dělat psí kusy.
Je ale na pováženou jestli není lepší pro běh aplikací podobných naší
testovací použít některý z aplikačních serverů. Pokud vaše aplikace
nepotřebuje vlastnosti a funkcionality aplikačního serveru a vystačí si se
Springem (jako to bylo v našem případě), myslím, že je Tomcat díky své
jednoduchosti dobrá volba.</p>

<h3>Odkazy</h3>

<ul>
	<li><a
	href="http://blog.itplace.cz/wp-content/uploads/tomcat-example.zip">http://blog.itplace.cz/…-example.zip</a> –
	testovací aplikace ke stažení.</li>

	<li><a href="http://tomcat.apache.org/">http://tomcat.apache.org/</a> –
	Apache Tomcat</li>

	<li><a href="http://ant.apache.org/">http://ant.apache.org/</a> – Apache
	Ant</li>

	<li><a href="http://java.sun.com/javase/">http://java.sun.com/javase/</a> –
	Java</li>
</ul>

<!-- by Texy2! -->]]></content:encoded>
			<wfw:commentRss>http://blog.itplace.cz/tomcat-sdileny-backend/feed/</wfw:commentRss>
		</item>
		<item>
		<title>VisualVM - vítězství v soutěži</title>
		<link>http://blog.itplace.cz/visualvm-vitez/</link>
		<comments>http://blog.itplace.cz/visualvm-vitez/#comments</comments>
		<pubDate>Sat, 15 Aug 2009 09:32:42 +0000</pubDate>
		<dc:creator>Jan Šmuk</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://blog.itplace.cz/?p=238</guid>
		<description><![CDATA[
<p>Náš článek VisualVM – tool for profiling Java applications zvítězil
v soutěži Java VisualVM Blogging Contest.</p>

<p>Článek popisuje, jak jsem postupoval při odhalování slabých míst ve
hře Java Dash. Neobsahuje ale řešení těchto problémů, což je velká
škoda. Slibuji, až bude čas, ještě se k tomu vrátím :)</p>

<p>Ale i přesto byl tento článek vybrán jako jeden z nejlepších
v poměrně silné konkurenci.</p>

<p>Odkazy</p>

<p><a
href="https://visualvm.dev.java.net/">https://visualvm.dev.java.net/</a> –<br
/>
VisualVM homepage, seznam dalších článků.</p>

<p><a
href="http://java.sun.com/">http://java.sun.com/</a>…avavisualvm/ –<br />
oficiální výsledky soutěže.</p>

<!-- by Texy2! -->]]></description>
			<content:encoded><![CDATA[
<p>Náš článek <a href="/visualvm">VisualVM – tool for profiling Java
applications</a> zvítězil v soutěži <a
href="http://java.sun.com/community/javavisualvm/">Java VisualVM Blogging
Contest</a>.</p>

<p>Článek popisuje, jak jsem postupoval při odhalování slabých míst ve
hře Java Dash. Neobsahuje ale řešení těchto problémů, což je velká
škoda. Slibuji, až bude čas, ještě se k tomu vrátím :)</p>

<p>Ale i přesto byl tento článek vybrán jako jeden z nejlepších
v poměrně silné konkurenci.</p>

<h3>Odkazy</h3>

<ul>
	<li><a
	href="https://visualvm.dev.java.net/">https://visualvm.dev.java.net/</a> –
	VisualVM homepage, seznam dalších článků.</li>

	<li><a
	href="http://java.sun.com/community/javavisualvm/">http://java.sun.com/…avavisualvm/</a> –
	oficiální výsledky soutěže.</li>
</ul>

<!-- by Texy2! -->]]></content:encoded>
			<wfw:commentRss>http://blog.itplace.cz/visualvm-vitez/feed/</wfw:commentRss>
		</item>
		<item>
		<title>VisualVM - tool for profiling Java applications</title>
		<link>http://blog.itplace.cz/visualvm/</link>
		<comments>http://blog.itplace.cz/visualvm/#comments</comments>
		<pubDate>Wed, 20 May 2009 09:15:05 +0000</pubDate>
		<dc:creator>Jan Šmuk</dc:creator>
		
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://blog.itplace.cz/?p=187</guid>
		<description><![CDATA[
<p>VisualVM is tool for profiling Java applications made by Sun. Today I would
like to write about my experience with it.</p>

<p>Some time ago I was experimenting with game programming in Java. I wrote
clone of famous Boulder Dash game. When playing the game on different machines
I found out that it eats terrible amount of CPU time. What? The original was
running nicely on […]</p>

<!-- by Texy2! -->]]></description>
			<content:encoded><![CDATA[
<p>VisualVM is tool for profiling Java applications made by Sun. Today I would
like to write about my experience with it.</p>

<p>Some time ago I was experimenting with game programming in Java. I wrote
clone of famous Boulder Dash game. When playing the game on different machines
I found out that it eats terrible amount of CPU time. What? The original was
running nicely on 8bits ZX Spectrum ;). I started looking into the code and
optimize it. Some hours later the performance got better but still not good
enough. I came to the point where I could<br />
not proceed any further. All my algorithms looked nice and clean. I delayed the
solution and left it as it was.</p>

<p>Recently I have heard about VisualVM and I decided to give it a try.</p>

<h3>Making it run</h3>

<p>Installation was smooth. I just downloaded the zip archive from <a
href="https://visualvm.dev.java.net/">https://visualvm.dev.java.net/</a>,
extracted it and run. The first run of VisualVM resulted into warning message:
Local Applications Cannot Be Detected. But the issue is nicely documented
directly on VisualVM site and the solution took me only few seconds (see <a
href="https://visualvm.dev.java.net/troubleshooting.html#jpswin">https://visualvm.dev.java.net/…hooting.html#…</a>
for details).</p>

<h3>Finding a big spender</h3>

<p>After I started-up the game i was able to see it as local java application
in VisualVM applications panel to the left:</p>

<div style="text-align:center" class="figure"><img
src="/wp-content/uploads/visualvm1.png" alt="VisualVM Monitor" />
	<p>VisualVM Monitor</p>
</div>

<p>As you can see it is using up to 80% of my 2.4GHz Sempron which is quite a
lot. I was going to find out what is eating so much performance so i clicked
on <em>Profiler</em> tab and opened the settings by checking the checkbox to
the right:</p>

<div style="text-align:center" class="figure"><img
src="/wp-content/uploads/visualvm3.png" alt="VisualVM Profiler" />
	<p>VisualVM Profiler</p>
</div>

<p>At first I left all settings as set by default except <em>Start profiling
from classes</em>, where I put <code>com.spekacek.boulder.**</code>. Then
I started up CPU profiling. Then I was playing the game for few moments –
profiling slows everything down so it was not a big fun. Then I hit
<em>Snapshot</em> button and I got following report:</p>

<div style="text-align:center" class="figure"><img
src="/wp-content/uploads/visualvm2.png" alt="VisualVM Profiler snapshot" />
	<p>VisualVM Profiler snapshot</p>
</div>

<p>In CPU snapshot view you can see how much time did it take to process each
method. In the case of my game the obvious winner is
<code>GamePanel.paintLevelData()</code> method. It was called 3858 times and
sum of the times spent calling it is 38865 miliseconds which is 70.2% of time
in <code>AWT-EventQueue-1</code> thread. Look at <code>Self time</code> item
right beneath <code>GamePanel.paintLevelData()</code>. This is time spend
calling not instrumented methods – methods which don't match with the
settings we did before starting the profiling.</p>

<p>To be able to look more deeply into what is going on in
<code>GamePanel.paintLevelData()</code> I started-up new profiling session.
this time I set <em>Start profiling from classes</em> to
<code>com.spekacek.boulder.view.GamePanel</code> and cleared everything in
<em>Do not profile classes</em> setting – I want to profile everything
starting from <code>com.spekacek.boulder.view.GamePanel</code> and I don't want
any exclusions. Then I started-up the CPU profiling again and after a while of
playing the game I made another snapshot. This is what I got:</p>

<div style="text-align:center" class="figure"><img
src="/wp-content/uploads/visualvm4.png" alt="VisualVM Profiler snapshot" />
	<p>VisualVM Profiler snapshot</p>
</div>

<p>Now you can see that inside <code>GamePanel.paintLevelData()</code> method
the biggest spender is <code>SunGraphics2D.drawImage()</code> method. It was
called 313218 times and sum of the times spent calling it is
21622 miliseconds.</p>

<p>So now I know where the problem lies and I can focus myself on fixing it.
I know that I have to paint game levels faster. I can try either to reduce
number of <code>SunGraphics2D.drawImage()</code> calls or find a faster
alternative. But this is not the topic of this article.</p>

<h3>Conclusion</h3>

<p>I like this tool. It is very simple an intuitive – not very different
from highly advanced JProfiler. It can do much more than I described in this
humble article including memory profiling, heap viewer, etc. In short it can
help you to find weak spots in your application for free. Good job guys! :)</p>

<h3>Some links</h3>

<ul>
	<li><a
	href="https://visualvm.dev.java.net/">https://visualvm.dev.java.net/</a> –
	VisualVM Homepage</li>

	<li><a
	href="http://en.wikipedia.org/wiki/Boulder_Dash">http://en.wikipedia.org/…Boulder_Dash</a> –
	some information about Boulder Dash, the best game ever.</li>

	<li><a href="http://boulder.spekacek.com/">http://boulder.spekacek.com/</a> –
	Java Dash homepage, including still not fully optimized Boulder Dash
	clone ;)</li>
</ul>

<!-- by Texy2! -->]]></content:encoded>
			<wfw:commentRss>http://blog.itplace.cz/visualvm/feed/</wfw:commentRss>
		</item>
		<item>
		<title>JSF and nice URLs - PrettyFaces</title>
		<link>http://blog.itplace.cz/jsf-and-nice-urls-prettyfaces/</link>
		<comments>http://blog.itplace.cz/jsf-and-nice-urls-prettyfaces/#comments</comments>
		<pubDate>Wed, 29 Apr 2009 21:28:38 +0000</pubDate>
		<dc:creator>Vlastimil Vávrů</dc:creator>
		
		<category><![CDATA[Articles in english]]></category>

		<category><![CDATA[JSF]]></category>

		<guid isPermaLink="false">http://blog.itplace.cz/?p=160</guid>
		<description><![CDATA[
<p>In this article I would like to introduce URL rewriting engine for JSF –
PrettyFaces and provide a maven archetype for quick startup.</p>

<p>The motivation for using rewriting engine in web development is
straightforward – nice URLs are better for SEO and easier to remember.</p>

<p>Integration of PrettyFaces</p>

<p>Integration of PrettyFaces in existing project is well described in
PrettyFaces documentation. Step are following:</p>

<p>Download PrettyFaces binary […]</p>

<!-- by Texy2! -->]]></description>
			<content:encoded><![CDATA[
<p>In this article I would like to introduce URL rewriting engine for JSF –
<a href="http://ocpsoft.com/tags/prettyfaces/">PrettyFaces</a> and provide a
maven archetype for quick startup.</p>

<p>The motivation for using rewriting engine in web development is
straightforward – nice URLs are better for <acronym
title="Search Engine Optimalization">SEO</acronym> and easier to remember.</p>

<h3>Integration of PrettyFaces</h3>

<p>Integration of PrettyFaces in existing project is well described in <a
href="http://ocpsoft.com/prettyfaces/v123/">PrettyFaces documentation</a>. Step
are following:</p>

<ol>
	<li>Download PrettyFaces binary and all dependencies and put them in classpath
	of your project.</li>

	<li>Define PrettyFaces filter in <code>/WEB-INF/web.xml</code>.</li>

	<li>Create config file <code>/WEB-INF/pretty-config.xml file</code>.</li>
</ol>

<p>That`s all! Now you can start to use it.</p>

<h4>URL mapping example</h4>

<pre
class="xml"><code>&lt;url-mapping id="viewItem"&gt;
        &lt;pattern&gt;/item/#{bean.selectedItem}/&lt;/pattern&gt;
        &lt;view-id&gt;/pages/viewItem.jsf&lt;/view-id&gt;
&lt;/url-mapping&gt;</code></pre>

<p>The URL mapping example above causes that any request in form
<code>/item/[anything here]/</code> will be served by
<code>/pages/viewItem.jsf</code> page. Value of
<code>#{bean.selectedItem}</code> expression will be evaluated during runtime
(getter of <code>selectedItem</code> property of managed bean <code>bean</code>
will be triggered).</p>

<p>On the other side – there is a simple way how to generate this link on JSF
template in consistent way. In other words – there is only one place with
rewriting rules. Once you change it there it is changed all across the project.
There are <a href="http://ocpsoft.com/prettyfaces/v123/#links">two
components</a> made for this purpose:</p>

<ul>
	<li><strong>pretty:link</strong> (similar as <code>c:url</code> but id of url
	mapping is used to refer the URL)</li>

	<li><strong>pretty:urlbuffer</strong> (similar as <code>pretty:link</code> but
	stores the URL in a variable instead of printing it immediatelly)</li>
</ul>

<pre
class="xml"><code>&lt;pretty:link mappingId="viewItem"&gt;
        &lt;f:param value="#{item}" /&gt;
        &lt;h:outputText value="#{item}" /&gt;
&lt;/pretty:link&gt;</code></pre>

<p>There are two more <code>&lt;url-mapping&gt;</code> subelements I would like
to mention:</p>

<ul>
	<li><strong>&lt;query-param name=""&gt;&lt;/query-param&gt;</strong> – let
	you specify query parameter and method that will return its value.</li>

	<li><strong>&lt;action phaseId=""
	onPostback=„fal­se“&gt;&lt;/action&gt;</strong> – let you specify the
	bean a method that will be called during specified Phase (default phase is
	<code>RESTORE_VIEW</code>). Another parameter is <code>onPostback</code> that
	says if method should be triggered during postback.</li>
</ul>

<h4>Navigation</h4>

<p>Instead of navigation rules stored in <code>faces-config.xml</code> you can
use PrettyFaces to navigate. There is a special prefix <strong>pretty:</strong>
you can use in method of managed beans. In case you return
<code>pretty:home</code> view id PrettyFaces will search for url mapping with id
<code>home</code> and redirect to this page. Or you can use just
<code>pretty:</code> to reditect to current page.</p>

<h3>PrettyFaces archetype</h3>

<p>As a base for my archetype I choose <a
href="http://code.google.com/p/deltaset/">Deltaset maven archetype</a> which
already includes JSF, Facelets and Richfaces. But there was one tricky
problem – a dependency on ` xerces:xercesIm­pl:jar:2.4.0` which causes a
SaxParser exception during Jetty start. This library was referenced from
<code>nekohtml</code>. The solution was quite simple – exclude old version of
xercesImpl and add a depencency on newer one.</p>

<h4>Steps to create project on your computer</h4>

<p>It is supposed you have <a href="http://maven.apache.org/">Maven</a>
installed on your computer.</p>

<ol>
	<li>Download and unzip <a
	href="http://blog.itplace.cz/wp-content/uploads/archetype-prettyfaces.zip">PrettyFaces
	maven archetype</a>.</li>

	<li>Install archetype into your local repository. Call <code>mvn install</code>
	in folder where you unzipped download archetype.</li>

	<li>Go to folder where you wanna create new project and call (replace
	<code>[group-id]</code> and <code>[artifact-id]</code> with real values)</li>
</ol>

<pre
class="xml"><code>mvn archetype:generate \
-DarchetypeGroupId=cz.itplace \
-DarchetypeArtifactId=archetype-prettyfaces \
-DarchetypeVersion=1.0-SNAPSHOT \
-DgroupId=[group-id] \
-DartifactId=[artifact-id]</code></pre>

<p>Now call <code>mvn jetty:run</code> to start Jetty container. Or <code>mvn
eclipse:eclipse</code> to generate an Eclipse project.</p>

<h4>Conclusion</h4>

<p>PrettyFaces is nice piece of code. Easy to understand and well
documented.</p>

<h4>Links</h4>

<ul>
	<li><a href="http://ocpsoft.com/tags/prettyfaces/">PrettyFaces homepage</a></li>

	<li><a
	href="http://blog.itplace.cz/wp-content/uploads/archetype-prettyfaces.zip">PrettyFaces
	maven archetype</a></li>
</ul>

<!-- by Texy2! -->]]></content:encoded>
			<wfw:commentRss>http://blog.itplace.cz/jsf-and-nice-urls-prettyfaces/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Effective search under a subtree</title>
		<link>http://blog.itplace.cz/effective-search-under-a-subtree/</link>
		<comments>http://blog.itplace.cz/effective-search-under-a-subtree/#comments</comments>
		<pubDate>Sat, 25 Apr 2009 15:53:29 +0000</pubDate>
		<dc:creator>Jan Šmuk</dc:creator>
		
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.itplace.cz/?p=123</guid>
		<description><![CDATA[
<p>Almost every blogging system supports assigning articles into categories and
subcategories. Listing articles which belong to a subtree of categories may be
quite expensive operation especially if the number of articles is very high. In
this article I would like to describe one of possible solutions.</p>

<p>Category Tree</p>

<p>Tree of article categories could look something like:</p>

<p>Music</p>

<p>Rock</p>

<p>Pop</p>

<p>Jazz</p>

<p>Sport</p>

<p>Snowboarding</p>

<p>Skiing</p>

<p>Cross-country skiing</p>

<p>Downhill skiing</p>

<p>Kiteboarding</p>

<p>Traveling</p>

<p>Adventure</p>

<p>Leisure</p>

<p>The most simple way […]</p>

<!-- by Texy2! -->]]></description>
			<content:encoded><![CDATA[
<p>Almost every blogging system supports assigning articles into categories and
subcategories. Listing articles which belong to a subtree of categories may be
quite expensive operation especially if the number of articles is very high. In
this article I would like to describe one of possible solutions.</p>

<h3>Category Tree</h3>

<p>Tree of article categories could look something like:</p>

<blockquote>
	<ul>
		<li>Music
			<ul>
				<li>Rock</li>

				<li>Pop</li>

				<li>Jazz</li>
			</ul>
		</li>

		<li>Sport
			<ul>
				<li>Snowboarding</li>

				<li>Skiing
					<ul>
						<li>Cross-country skiing</li>

						<li>Downhill skiing</li>
					</ul>
				</li>

				<li>Kiteboarding</li>
			</ul>
		</li>

		<li>Traveling
			<ul>
				<li>Adventure</li>

				<li>Leisure</li>
			</ul>
		</li>
	</ul>
</blockquote>

<p>The most simple way of assigning an article to a category would be to give
each category an id (e.g. Music=1, Rock=2, Pop=3, Jazz=4, Sport=5,…) and add
categoryId column into Article database table. Then if we wanted to get all
articles from category Rock we could do it simply by running
something like:</p>

<pre class="sql"><code><span class="sql-keyword1">select</span> * <span
class="sql-keyword1">from</span> Article <span
class="sql-keyword1">where</span> categoryId=<span
class="sql-num">2</span></code></pre>

<p>But getting all articles from all subtree under Music category will be more
complicated, we have to make list of category ids from all Music subtree and
query something like:</p>

<pre class="sql"><code><span class="sql-keyword1">select</span> * <span
class="sql-keyword1">from</span> Article <span
class="sql-keyword1">where</span> categoryId <span
class="sql-keyword1">in</span> (<span class="sql-num">1</span>,<span
class="sql-num">2</span>,<span class="sql-num">3</span>,<span
class="sql-num">4</span>)</code></pre>

<p>Imagine much larger category tree, the number of categories in a subtree may
be high. We wanted something more efficient and still we would like to be able
to add new categories into a tree.</p>

<h3>Limited tree</h3>

<p>In our project the efficiency was really top priority, therefore we were able
to accept slight limitations to our category tree which could give us better
performance:</p>

<ul>
	<li>Maximum tree depth is defined once and then constant. Let's name this
	parameter <code>maxLevels</code>.</li>

	<li>Maximum number of children a parent may have is defined once and then
	constant. This parameter can be called <code>maxChildren</code>.</li>
</ul>

<h3>Limited tree evaluation</h3>

<p>Position of every tree node can be described by path to it from the tree
root. Look at following tree:</p>

<blockquote>
	<ul>
		<li>Music {1}
			<ul>
				<li>Rock {1,1}</li>

				<li>Pop {1,2}</li>

				<li>Jazz {1,3}</li>
			</ul>
		</li>

		<li>Sport {2}
			<ul>
				<li>Snowboarding {2,1}</li>

				<li>Skiing {2,2}
					<ul>
						<li>Cross-country skiing {2,2,1}</li>

						<li>Downhill skiing {2,2,2}</li>
					</ul>
				</li>

				<li>Kiteboarding {2,3}</li>
			</ul>
		</li>

		<li>Traveling {3}
			<ul>
				<li>Adventure {3,1}</li>

				<li>Leisure {3,2}</li>
			</ul>
		</li>
	</ul>
</blockquote>

<p>Path can have maximally <code>maxLevels</code> items and each item in path is
in range from 1 to <code>maxChildren</code>. For simplification we filled paths
shorter then <code>maxLevels</code> by 0s. So for example if <code>maxLevels =
6</code> then path to Pop node is <code>{1,2,0,0,0,0}</code>. Then we can
express a path as <code>int</code> array of size <code>maxLevels</code>.</p>

<p>Now for each node we can calculate a single integral value using this
equation (the operator <code>^</code> means power):</p>

<pre>value(path) = path[0]*(maxChildren+1)^(maxLevels-1)
 + path[1]*(maxChildren+1)^(maxLevels-2)
 + path[2]*(maxChildren+1)^(maxLevels-3)
 + ...
 + path[maxLevels-1]*(maxChildren+1)</pre>

<p>Does this equation resemble something to you? Yes you have seen it before, it
is equation for conversion a number from numeric system with base (maxLevels+1)
into decimal system.</p>

<p>Into Article table we add new column <code>categoryValue</code> into which we
will put the calculated value based on a category an article belongs to.</p>

<h3>Example</h3>

<p>Now why we did all this? Let me show you on example. The tree we will use
looks the same as above. At first we have to define <code>maxLevels</code> and
<code>maxChildren</code> parameters. Let's define <code>maxLevels=4</code> and
<code>maxChildren=7</code> (When evaluating tree nodes we will therefore convert
number from octal system into decimal.)</p>

<p>We have written a new article and we want to assign it to category Skiing
(path is {2,2} which is equal to {2,2,0,0}). So we can calculate the
<code>categoryValue</code> column value using equation defined above:</p>

<pre>value(Skiing {2,2,0,0}) = 2*8^3 + 2*8^2 + 0*8^1 + 0*8^0 = 1024 + 128 = 1152</pre>

<p>Then let's say we want to list all articles from category Sport {2} and
below. It means everything between Sport {2} inclusive and Traveling {3} (which
is next sibling to Sport) exclusive. So we calculate lower and upper limits:</p>

<pre>lower = value(Sport {2,0,0,0}) = 2*8^3 + 0*8^2 + 0*8^1 + 0*8^0 = 1024
upper = value(Traveling {3,0,0,0}) = 3*8^3 + 0*8^2 + 0*8^1 + 0*8^0 = 1536</pre>

<p>The sql to get all articles from under the Sport node is then:</p>

<pre>select * from Article where categoryValue &gt;= :lower and categoryValue &lt; :upper</pre>

<p>It looks more complicated then it really is. For testing we use
<code>maxChildren=9</code> because then paths form direcly decimal numbers. For
example when <code>maxLevels=5</code> then:</p>

<pre>value(2,3,4) = value(2,3,4,0,0) = 23400</pre>

<h3>Real life</h3>

<p>Tree parameters are limited by type we store calculated value in. We used
<code>long</code> java type which is 64 bits type. We set
<code>maxLevels=6</code> and <code>maxChildren=10</code>. It is sufficient for
our needs and very fast.</p>

<!-- by Texy2! -->]]></content:encoded>
			<wfw:commentRss>http://blog.itplace.cz/effective-search-under-a-subtree/feed/</wfw:commentRss>
		</item>
		<item>
		<title>OAuth - představení autentizačního protokolu</title>
		<link>http://blog.itplace.cz/oauth-predstaveni-autentizacniho-protokolu/</link>
		<comments>http://blog.itplace.cz/oauth-predstaveni-autentizacniho-protokolu/#comments</comments>
		<pubDate>Mon, 13 Apr 2009 20:29:39 +0000</pubDate>
		<dc:creator>Vlastimil Vávrů</dc:creator>
		
		<category><![CDATA[Internet obecně]]></category>

		<guid isPermaLink="false">http://blog.itplace.cz/?p=84</guid>
		<description><![CDATA[
<p>OAuth autentizace umožňuje uživatelům sdílet data, texty, fotografie a
videa uložená jednom serveru, s jiným serverem, aniž by museli vyzradit
svoje přístupové údaje.</p>

<!-- by Texy2! -->]]></description>
			<content:encoded><![CDATA[
<p>V dnešním článku popíšu princip fungování autentizačního protokolu
OAuth a důvody pro jeho použití.</p>

<h3>K čemu je OAuth?</h3>

<p>Součástí jednoho našeho projektu byla integrace se sociálními sítěmi
(synchronizace kontaktů, statusů přátel, zpráv, multimediální galerie).
V našem případě to byly: Facebook, Twitter, Gmail, MSN a YouTube. Všechny
uvedené servery mají veřejné API, pomocí kterého lze k jeho funkcím
přistupovat. V prvních prototypech jsme v našich konektorech pro
autentizaci používali uživatelské jméno heslo (používala se <a
href="http://en.wikipedia.org/wiki/Basic_access_authentication">HTTP basic
autentizace</a>. V reálné aplikace není z různých důvodů (bezpečnost)
možné uživatelské jméno a heslo ukládat do databáze. A právě k tomu
je <a href="http://oauth.net/">OAuth</a>.</p>

<p><strong>OAuth autentizace umožňuje uživatelům sdílet data, texty,
fotografie a videa uložená jednom serveru, s jiným serverem, aniž by museli
vyzradit svoje přístupové údaje</strong>.</p>

<h3>Jak OAuth funguje?</h3>

<p>Nejdříve si představíme základní pojmy:</p>

<ul>
	<li><strong>Service provider</strong> – služba, která obsahuje chráněné
	zdroje a má být chráněna. Může se jednat o bankovní server,
	mikroblogovací server, nebo server pro správu obrázků.</li>

	<li><strong>Uživatel</strong> – reálný uživatel služby (Service
	provideru), vlastník chráněného obsahu.</li>

	<li><strong>Consumer</strong> – aplikace přistupující k chráněným
	zdrojům uživatele. Zdroje leží na service provideru.</li>

	<li><strong>Chráněný zdroj</strong> – obsah uživatele (data, texty,
	obrázky, videa), který chce chránit.</li>
</ul>

<p>Nejdříve je nutné consumer u service providera zaregistrovat. Způsoby
registrace jsou různé. Nejčastěji je to webové rozhraní. Rovnou uvedu
příklad – zvolím si Twitter. Mějme aplikaci, která se bude připojovat
na Twitter (tato aplikace je <em>consumer</em>) a bude si stahovat naše
nejnovější zprávy.</p>

<p>V případě Twitteru se přidá (zaregistruje) nová aplikace zde – <a
href="http://twitter.com/oauth_clients/new">Register an Application</a> (pro
přidání aplikace musíte mít účet na Twitteru a být přihlášeni). Pro
ty z vás co nemají účet na Twitteru uvedu přehled nejdůležitějších
vlastností, které je možné u aplikace vyplnit:</p>

<ul>
	<li>jméno, popis, domovská stránka aplikace</li>

	<li>callback URL (adresa, na kterou bude uživatel přesměrován po
	nastavení práv)</li>

	<li>typ přístupu (read only, read and write)</li>
</ul>

<div style="text-align:center" class="figure"><img
src="/wp-content/uploads/oauth/twitter-itplace-test-app-s.png"
alt="Naše aplikace v Twitteru" />
	<p>Naše aplikace v Twitteru</p>
</div>

<p>Parametry aplikace nejsou povinné. Ty, jež jsem uvedl, platí pouze pro
Twitter a nejsou součástí specifikace OAuth. V jiné aplikace může být
např. granularita přístupových práv mnohem jemnější (např. přístup
pouze do určitého adresáře s fotkami a na omezenou dobu).</p>

<p>Výsledkem registrace consumera je <strong>consumer key</strong> a
<strong>consumer secret</strong>. Consumer key identifikuje consumera. Consumer
secret slouží pro <a
href="http://www.hueniverse.com/hueniverse/2008/10/beginners-gui-1.html">podepisování
požadavku</a>.</p>

<h4>1) Získání request tokenu</h4>

<p>Uživatel je na webu consumera a klepne na tlačítko (odkaz) pro získání
přístupu. Odkaz vede na web consumera a provede se následující:</p>

<p><a href="http://oauth.net/core/1.0/#auth_step1">Získání request
tokenu</a> – provede se na serverové straně consumera (např pomocí <a
href="http://hc.apache.org/httpclient-3.x/">HttpClient</a> nebo standardní <a
href="http://java.sun.com/j2se/1.4.2/docs/api/java/net/HttpURLConnection.html">HttpURLConnec­tion</a>.
Na straně consumera je service provider identifikován třemi URL:</p>

<ul>
	<li>URL pro získání request tokenu (pro Twitter je to <a
	href="http://twitter.com/oauth/request_token">http://twitter.com/…equest_token</a>)</li>

	<li>URL pro autentizaci uživatele</li>

	<li>URL pro výměnu request token za access token</li>
</ul>

<p>HTTP request z consumera na service provider musí být podle OAuth
standardů. Musí obsahovat <a
href="http://oauth.net/core/1.0/#auth_step1">povinné parametry</a> (ty musí
být správně <a
href="http://oauth.net/core/1.0/#encoding_parameters">encodovány</a>) a být <a
href="http://oauth.net/core/1.0/#signing_process">podepsán</a>.</p>

<p>Povinné parametry:</p>

<ul>
	<li>oauth_consumer_key: The Consumer Key.</li>

	<li>oauth_signatu­re_method – typ šifrování použitý pro signature
	(podpis) requestu (PLAINTEXT, HMAC-SHA1, RSA-SHA1)</li>

	<li>oauth_signature – podpis zprávy (postup vytvoření podpisu bude
	popsán)</li>

	<li>oauth_timestamp – klasický Unix timestamp označující dobu vytvoření
	requestu</li>

	<li>oauth_nonce – unikátní číslo requestu</li>

	<li>oauth_version – verze (nepovinný parametr). Současná hodnota
	je 1.0.</li>
</ul>

<p>Vytvoření podpisu (hodnoty parameru oauth_signature):</p>

<ol>
	<li>Shromáždí se veškeré parametry (kromě parametru „realm“) –
	query parametry, POST parametry, parametry z OAuth hlavičky</li>

	<li>Parametry se převedou do kódování UTF-8 (kromě binárních dat) a
	provede se URL encodování</li>

	<li>Parametry jsou <a href="http://oauth.net/core/1.0#anchor14">seřazeny</a>
	podle abecedy a spojeny v jeden řetězec</li>

	<li>Z řetězce se pomocí consumer secret a token secret vygeneruje podpis a
	přidá se jako parametr oauth_signature do requestu</li>
</ol>

<p>Výsledný request:</p>

<pre><code>GET /oauth/request_token HTTP/1.1
Host: twitter.com:80
Authorization: OAuth realm="http://twitter.com/oauth/request_token"
    oauth_consumer_key="asdfasqeiou235sd"
    oauth_token=""
    oauth_nonce="2345667878"
    oauth_timestamp="1230768000"
    oauth_signature_method="HMAC-SHA1"
    oauth_version="1.0"
    oauth_signature="4TbFhc%2FDKyGswotg39339AR4J5k%3D"</code></pre>

<p>Výsledkem zavolání requestu je <em>request token</em> a <em>request token
secret</em>.</p>

<h4>2) Přesměrování na stranu service providera</h4>

<p>Uživateli je vrácen response, který v hlavičce <strong>přesměrovává
na URL pro autentizaci uživatele na straně service providera</strong>.
V případě Twitteru je to adresa <a
href="http://twitter.com/oauth/authorize">http://twitter.com/oauth/authorize</a>.
Jako parametry jsou poslány request token (získaný v předchozím kroku) a
volitelně <strong>callback URL</strong> (adresa pro přesměrování po
nastavení přístupových práv na straně service providera).</p>

<h4>3) Nastavení přístupových práv</h4>

<p>Na straně service providera se uživatel přihlásí a povolí consumerovi
přistupovat k aplikaci. O různých typech přístupových práv jsem mluvil
dříve v článku.</p>

<h4>4) Přesměrování zpět na consumera</h4>

<p>Následuje přesměrování zpět na consumera na zadanou callback URL. Jako
parametr je poslán <strong>request token</strong>, aby consumer věděl,
k čemu vlastně byla práva nastavena.</p>

<h4>5) Consumer požádá o access token</h4>

<p>Consumer na straně serveru vytvoří HTTP request stejně jako v bodu
1 při získávání request tokenu. Rozdíl je v cílové URL service
providera – nyní je to URL pro výměnu request token za access token. Pro
Twitter je to <a
href="http://twitter.com/oauth/access_token">http://twitter.com/…access_token</a>.
Když je přístup pro daný request token povolen, je navrácen <strong>access
token</strong> a <strong>access token secret</strong>. Tím je celý proces
dokončen.</p>

<p>Access token je součástí OAuth hlavičky, access token secret se
používá současně s consumer secret pro podepsání requestu.</p>

<p>Předchozích 5 bodů musí uživatel v ideálním případě obsolvovat
pouze jednou. Záleží na typu aplikace – někdy se nastavuje přístup na
omezenou dobu. Pak záleží pouze na tom, zda service provider po nějaké
době access token nevyexpiruje. Podle našich zkušeností to ale tak
nevypadá. Např. Google tvrdí, že access token neexpiruje nikdy.</p>

<h4>Přístup consumera k chráněnému zdroji</h4>

<p>Nyní může consumer přistupovat k chráněným zdrojům. Abyste dostali
lepší představu co mohou být chráněné zdroje, a jak k nim přistupovat,
podívejte se na <a
href="http://apiwiki.twitter.com/REST+API+Documentation">Twitter API</a>. Např.
pomocí metody <a
href="http://apiwiki.twitter.com/REST+API+Documentation#friends/ids">http://twitter.com/friends/ids.xml</a>
můžete dostat všechny přátele vybraného uživatele.</p>

<h4>Jak je to s podporou OAuth u sociální sítí a dalších webů?</h4>

<p>Přímo na domovském webu OAuth je možné se dočíst, že jej podporují
následující weby: Digg, Jaiku, Flickr, Ma.gnolia, Plaxo, Pownce, Twitter, and
hopefully Google, Yahoo. Článek, který informace obsahuje je téměr 2 roky
starý, takže nyní bude situace ještě o mnoho lepší. Např Twitter,
který má OAuth podporu stále jenom v beta provozu, tvrdí, že po jeho
ostrém spuštění po nějaké době zruší možnost autentizace pomocí HTTP
basic authentication. Cituji:</p>

<blockquote>
	<p>Can my application continue to use Basic Auth?<br />
	There is no requirement to move to OAuth at this time. If/When a date is set for
	the deprecation of Basic Auth we will publish a notice on the API Development
	Talk. We will not set a date for deprecation until several outstanding issues
	have been resolved. When we do set a date we plan to provide at least six months
	to transition.</p>
</blockquote>

<h4>Rozdíl mezi OAuth a OpenID</h4>

<p><a href="http://openid.net/">OpenID</a> neskrývá identitu uživatele.
Slouží pouze k jejímu ověření. Zatímco pomocí OAuth umožňuje
přístup ke zdrojům bez přímého udání identity uživatele
(uživatelského jméne, hesla a další osobních údajů). Každý
z autentizačních mechanizmů se proto hodí pro různé použití. Bez
zajímavosti není, že oba protokoly mají společné autory.</p>

<h4>Závěr</h4>

<p>OAuth je dnes již standardním způsobem autentizace, který používají
největší hráči na trhu (Google, Yahoo, YouTube, Twitter). Čas investovaný
do jeho porozumění a implementace se rozhodně vyplatí.</p>

<h4>Odkazy</h4>

<ul>
	<li><a href="http://oauth.net/">OAuth</a></li>

	<li><a href="http://oauth.net/core/1.0/">OAuth Core 1.0 –
	specification</a></li>

	<li><a href="http://code.google.com/p/oauth/">OAuth on google code</a></li>

	<li><a
	href="http://www.hueniverse.com/hueniverse/2007/10/beginners-guide.html">Beginner’s Guide
	to OAuth</a></li>

	<li><a href="http://spring-security-oauth.codehaus.org/">OAuth for Spring
	Security</a></li>

	<li><a
	href="http://zdrojak.root.cz/clanky/oauth-novy-protokol-pro-autentizaci-k-vasemu-api/">OAuth –
	nový protokol pro autentizaci k vašemu API</a></li>
</ul>

<!-- by Texy2! -->]]></content:encoded>
			<wfw:commentRss>http://blog.itplace.cz/oauth-predstaveni-autentizacniho-protokolu/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Jak si JBPM rozumí se Springem</title>
		<link>http://blog.itplace.cz/jak-si-jbpm-rozumi-se-springem/</link>
		<comments>http://blog.itplace.cz/jak-si-jbpm-rozumi-se-springem/#comments</comments>
		<pubDate>Thu, 09 Apr 2009 06:53:21 +0000</pubDate>
		<dc:creator>Jan Šmuk</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[JBPM]]></category>

		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://blog.itplace.cz/?p=45</guid>
		<description><![CDATA[
<p>V posledním článku <a
href="http://blog.itplace.cz/jak-jsme-pouzili-jbpm/">Jak jsme použili JBPM</a>
jsem popsal, jak a proč jsme použili JBPM. Dnes se podělím o naše
zkušenosti s integrací se Springem.</p>

<!-- by Texy2! -->]]></description>
			<content:encoded><![CDATA[
<p>V posledním článku <a
href="http://blog.itplace.cz/jak-jsme-pouzili-jbpm/">Jak jsme použili JBPM</a>
jsem popsal, jak a proč jsme použili JBPM. Dnes se podělím o naše
zkušenosti s integrací se Springem.</p>

<p>Spring a JBPM se v jednom z projektů, kde jsme oba použili, stýkají ve
dvou místech:</p>

<ol>
	<li>Konfigurace – můžeme například potřebovat, aby JBPM použil pro
	svůj běh již existující nakonfigurovanou hibernate session factory, kterou
	používá i zbytek naší aplikace.</li>

	<li>Spouštění akcí – chceme, aby akce byly součástí našeho spring
	kontextu.</li>
</ol>

<h3>Spring Modules</h3>

<p>Začali jsme tím, že jsme použili <a
href="https://springmodules.dev.java.net/docs/reference/0.8/html/jbpm31.html">springmodules-jbpm31</a>,
který již řeší oba výše zmíněné body. Takto může vypadat kousek
definice spring kontextu:</p>

<pre><code>...
&lt;!-- jBPM configuration --&gt;
&lt;bean id="jbpmConfiguration"
    class="org.springmodules.workflow.jbpm31.LocalJbpmConfigurationFactoryBean"&gt;
  &lt;property name="sessionFactory" ref="sessionFactory" /&gt;
  &lt;property name="configuration" value="classpath:jbpm.cfg.xml" /&gt;
  &lt;property name="createSchema" value="false" /&gt;
  &lt;property name="processDefinitionsResources"&gt;
    &lt;list&gt;
      &lt;value&gt;classpath:createArticle.xml&lt;/value&gt;
      &lt;value&gt;classpath:updateArticle.xml&lt;/value&gt;
    &lt;/list&gt;
  &lt;/property&gt;
&lt;/bean&gt;
...</code></pre>

<p>Jak springmodules řeší druhý bod, tedy spouštění akcí? Podlě mě ne
příliš šikovně. Představme si akci, která posílá uživateli email.
Chceme použít <acronym title="Inversion of Control">Ioc</acronym>
k nastavení reference na objekt, který bude obstarávat posílání emailů.
Springmodules toto řeší použitím bean proxy, které řekneme id našeho
action handleru ve spring kontextu. Deklarace takové akce pak vypadá
nějak takto:</p>

<pre>...
&lt;action name="myAction" config-type="bean"
   class="org.springmodules.workflow.jbpm31.JbpmHandlerProxy"&gt;
 &lt;targetBean&gt;sendEmailActionHandler&lt;/targetBean&gt;
 &lt;factoryKey&gt;jbpmConfiguration&lt;/factoryKey&gt;
&lt;/action&gt;
...</pre>

<p>Všimněte si atributu <code>config-type</code>. Pokud je jeho hodnota
<code>bean</code>, pak JBPM při vykonávání akce vytváří novou instanci
třídy specifikované v atributu <code>class</code>. Poté nastavuje této
instanci její vlastnosti na základě jmen a obsahů vnořených tagů. Tedy ve
výše uvedeném případě je vytvořena nová instance třídy
<code>org.springmodules.workflow.jbpm31.JbpmHandlerProxy</code> a jsou na ni
zavolány metody <code>setTargetBean("sendEmailActionHandler")</code> a
<code>setFactoryKey("jbpmConfiguration")</code>, což jsou vlastnosti nutné
k fungování této proxy.</p>

<h3>Malý trik</h3>

<p>Zdá se vám tento způsob složitý? Mi se zdál složitý až zbytečně
moc. Jednak takto sestavené akce hyzdí definici procesu. Dále jste si jistě
všimli, že zde chybí definice těla posílaného emailu a adresa příjemce.
Nenašel jsem lepší způsob, jak mít tyto dvě hodnoty přímo v definici
procesu, než je ukládat jako procesní proměnné. Proto jsem hledal způsob,
jak být schopen definovat akci ve stylu:</p>

<pre>...
&lt;action name="myAction" config-type="bean"
   class="itplace.jbpm.SendEmailActionHandler"&gt;
 &lt;emailAddress&gt;recipient@server.com&lt;/emailAddress&gt;
 &lt;emailBody&gt;hello&lt;/factoryKey&gt;
&lt;/action&gt;
...</pre>

<p>Samotná akce pak bude vypadat takto:</p>

<pre class="java"><code><span
class="java-keywords1">package</span> itplace.jbpm;

<span
class="java-keywords1">import</span> org.jbpm.graph.def.ActionHandler;
<span
class="java-keywords1">import</span> org.jbpm.graph.exe.ExecutionContext;

<span
class="java-keywords1">public</span> <span
class="java-keywords1">class</span> SendEmailActionHandler <span
class="java-keywords1">implements</span> ActionHandler {
  <span
class="java-keywords1">private</span> EmailSender emailSender;
  <span
class="java-keywords1">private</span> String emailAddress;
  <span
class="java-keywords1">private</span> String emailBody;

  <span
class="java-keywords1">public</span> <span
class="java-keywords1">void</span> execute(ExecutionContext executionContext) <span
class="java-keywords1">throws</span> Exception {
    emailSender.send(emailAddress, emailBody);
  }

  <span
class="java-keywords1">public</span> <span
class="java-keywords1">void</span> setEmailSender(EmailSender emailSender) {
    <span
class="java-keywords1">this</span>.emailSender = emailSender;
  }

  <span
class="java-keywords1">public</span> <span
class="java-keywords1">void</span> setEmailAddress(String emailAddress) {
    <span
class="java-keywords1">this</span>.emailAddress = emailAddress;
  }

  <span
class="java-keywords1">public</span> <span
class="java-keywords1">void</span> setEmailBody(String emailBody) {
    <span
class="java-keywords1">this</span>.emailBody= emailBody;
  }

}</code></pre>

<p>K identifikací našich akci ve spring kontextu jsme použili konvenci
pojmenovávání:</p>

<ul>
	<li>pokud je hodnota atributu <code>class</code> například
	<code>itplace.jbpm.SendEmailActionHandler</code>, pak budeme ve spring kontextu
	hledat bean s id <code>sendEmailActionHandler</code> – tedy jednoduché
	jméno třídy s malým písmenkem na začátku. Definice naši akce ve spring
	kontextu tedy bude:</li>
</ul>

<pre>...
&lt;bean id="sendEmailActionHandler" class="itplace.jbpm.SendEmailActionHandler"
    singleton="true"&gt;
  &lt;property name="emailSender" ref="emailSender"/&gt;
&lt;/bean&gt;
...</pre>

<p>Nyní potřebujeme JBPM donutit, aby nevytvářelo novou instanci třídy
akce, ale aby se použil bean definovaný ve spring kontextu s identifikací
odpovídající konvenci. Poté už JBPM může standardně nastavit vlastnosti
<code>emailAddress</code> a <code>emailBody</code>.</p>

<p>JBPM si ve třídě <code>Delegation</code> drží statickou mapu objektů
typu Instantiator. Instantiator je zodpovědný za vytváření instancí akcí.
Klíčem v této mapě je <code>String</code> a JBPM v této mapě hledá
Instantiator podle obsahu atributu <code>config-type</code>. Standardně je pod
klíčem <code>bean</code> v mapě uložený BeanInstantiator. Mým cílem bylo
tento rozšířit.</p>

<p>Nejprve jsem si vytvořil třídu, která mi umožní obecně manipulovat
s mapou instantiatorů:</p>

<pre class="java"><code><span
class="java-keywords1">package</span> itplace.jbpm;

<span
class="java-keywords1">import</span> java.util.Map;
<span
class="java-keywords1">import</span> org.jbpm.instantiation.Delegation;
<span
class="java-keywords1">import</span> org.jbpm.instantiation.Instantiator;

<span
class="java-keywords1">public</span> <span
class="java-keywords1">class</span> AdditionalInstantiatorsDeclaration <span
class="java-keywords1">extends</span> Delegation {
  <span
class="java-keywords1">public</span> <span
class="java-keywords1">void</span> setInstantiators(Map&lt;String, Instantiator&gt; instantiators) {
    instantiatorCache.putAll(instantiators);
  }
}</code></pre>

<p><code>instantiatorCache</code> je ona zmíněná statická mapa, do které
nyní můžeme přidat libovolný instantiator pod libovolným jménem. Náš
nový instantiator vypadá nějak takto:</p>

<pre class="java"><code><span
class="java-keywords1">package</span> itplace.jbpm;

<span
class="java-keywords1">import</span> org.jbpm.instantiation.BeanInstantiator;
<span
class="java-keywords1">import</span> org.springframework.beans.factory.BeanFactory;
<span
class="java-keywords1">import</span> org.springframework.beans.factory.BeanFactoryAware;

<span
class="java-keywords1">public</span> <span
class="java-keywords1">class</span> SpringInstantiator <span
class="java-keywords1">extends</span> BeanInstantiator
      <span
class="java-keywords1">implements</span> BeanFactoryAware {
    <span
class="java-keywords1">private</span> BeanFactory beanFactory;

    <span
class="java-keywords1">protected</span> Object newInstance(Class clazz) {
        String beanName = clazz.getSimpleName();
        beanName = beanName.substring(<span
class="java-num">0</span>, <span
class="java-num">1</span>).toLowerCase()
          + beanName.substring(<span
class="java-num">1</span>);
        <span
class="java-keywords1">if</span> (beanFactory.containsBean(beanName)) {
            <span
class="java-keywords1">return</span> beanFactory.getBean(beanName);
        }

        <span
class="java-keywords1">return</span> <span
class="java-keywords1">super</span>.newInstance(clazz);
    }

    <span
class="java-keywords1">public</span> <span
class="java-keywords1">void</span> setBeanFactory(BeanFactory beanFactory) {
        <span
class="java-keywords1">this</span>.beanFactory = beanFactory;
    }
}</code></pre>

<p><code>SpringInstantiator</code> implementuje rozhraní
<code>BeanFactoryAware</code>, takže se spring postará o vložení bean
factory. A pak jsme rozšířili standardní <code>BeanInstantiator</code> a
změnili chování metody <code>newInstance</code>, která nyní nejprve hledá
v bean factory bean podle konvence a pokud jej nenajde pouze vytvoří novou
instanci.</p>

<p>Do spring kontextu je tedy zapotřebí přidat následující:</p>

<pre><code>...
&lt;bean id="additionalInstantiatorsDeclaration"
    class="itplace.jbpm.AdditionalInstantiatorsDeclaration"&gt;
  &lt;property name="instantiators"&gt;
    &lt;map&gt;
      &lt;entry&gt;
        &lt;key&gt;&lt;value&gt;bean&lt;/value&gt;&lt;/key&gt;
        &lt;bean class="itplace.jbpm.SpringInstantiator" /&gt;
      &lt;/entry&gt;
    &lt;/map&gt;
  &lt;/property&gt;
&lt;/bean&gt;
...</code></pre>

<p>Je ještě vhodné říct springu, že JBPM je závislý na beanu
<code>additionalInstantiatorsDeclaration</code>, stačí přidat
<code>depends-on</code> atribut do JBPM konfigurace:</p>

<pre><code>...
&lt;!-- jBPM configuration --&gt;
&lt;bean id="jbpmConfiguration" depends-on="additionalInstantiatorsDeclaration"
    class="org.springmodules.workflow.jbpm31.LocalJbpmConfigurationFactoryBean"&gt;
...</code></pre>

<h3>Závěr</h3>

<p>Viděli jste, jak jednoduše lze JBPM integrovat se Springem. Také jste si
možná udělali obrázek o zdařilosti a praktičnosti spring jbpm modulu.
Způsob, který jsem vám předvedl, naprosto vyhovuje našim požadavkům a
funguje opravdu velmi dobře.</p>

<h3>Zdroje:</h3>

<ul>
	<li><a
	href="https://springmodules.dev.java.net/docs/reference/0.8/html/jbpm31.html">springmodules-jbpm31</a></li>
</ul>

<!-- by Texy2! -->]]></content:encoded>
			<wfw:commentRss>http://blog.itplace.cz/jak-si-jbpm-rozumi-se-springem/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Jak jsme použili JBPM</title>
		<link>http://blog.itplace.cz/jak-jsme-pouzili-jbpm/</link>
		<comments>http://blog.itplace.cz/jak-jsme-pouzili-jbpm/#comments</comments>
		<pubDate>Sun, 29 Mar 2009 15:29:40 +0000</pubDate>
		<dc:creator>Jan Šmuk</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[JBPM]]></category>

		<guid isPermaLink="false">http://blog.spekacek.com/?p=16</guid>
		<description><![CDATA[
<p>V tomto článku bych se chtěl podělit o praktické zkušenosti s JBPM
((Jboss Business Process Management)). Článek neobsahuje všechny informace
ani výčet všech vlastností JBPM, mým cílem je vám ukázat, jak jsme JBPM
použili v jednom z našich projektů.</p>

<!-- by Texy2! -->]]></description>
			<content:encoded><![CDATA[
<p>V tomto článku bych se chtěl podělit o praktické zkušenosti
s <acronym title="Jboss Business Process Management">JBPM</acronym>. Článek
neobsahuje všechny informace ani výčet všech vlastností JBPM, mým cílem
je vám ukázat, jak jsme JBPM použili v jednom z našich projektů.</p>

<h3>Zadání</h3>

<p>Představte si následující požadavek na váš nový blogovací
systém:</p>

<p>Uživatel přidává nový článek. Na základě konfigurace se provede
jedna z těchto variant:</p>

<ul>
	<li>Bez moderace: Článek je ihned vytvořen a zveřejněn.</li>

	<li>Moderace apriori: Článek je vytvořen, poslán k ověření moderátorem,
	pokud jej moderátor akceptuje, je zveřejněn.</li>

	<li>Moderace aposteriori: Článek je vytvořen a zveřejněn, poslán
	k ověření moderátorem, pokud jej moderátor odmítne, je označen jako
	neveřejný.</li>
</ul>

<h3>Analýza</h3>

<p>Jaké operace nad článkem tedy náš systém musí podporovat?</p>

<ul>
	<li>Vytvořit neveřejný článek;</li>

	<li>zveřejnit článek;</li>

	<li>zneveřejnit článek;</li>

	<li>smazat článek;</li>

	<li>poslat článek ke schválení moderací.</li>
</ul>

<p>Z těchto operací nyní můžeme sestavit kteroukoli z variant.
Nejjednodušší je v našem případě varianta bez moderace, my se však
zaměříme na variantu moderace apriori. Konfigurace našeho systému musí
definovat, která z variant se provede, tedy které operace, v jakém pořadí
a za jakých podmínek se provedou – jinými slovy konfigurace musí
definovat proces vytvoření článku. Samotná moderace může nějakou chvíli
trvat, bude tedy třeba provádění procesu po odeslání článku k moderaci
přerušit a pokračovat až moderátor o článku rozhodne. Variantu moderace
apriori můžeme znázornit jako stavový diagram:</p>

<div style="text-align:center" class="figure"><img
src="/wp-content/uploads/apriorimoderation.png" alt="Moderace apriori" />
	<p>Schéma moderace apriori</p>
</div>

<h3>Návrh</h3>

<p>Jak funguje moderace? Poslání článku k moderaci si můžeme představit
jako přidání článku do fronty. Moderátor tento článek z fronty vybere a
rozhodne. Je tedy zřejmé že náš proces musíme rozdělit do dvou
asynchronních částí, provádění bude probíhat ve dvou vláknech:</p>

<p>Vlákno 1:</p>

<ol>
	<li>vytvoř neveřejný článek</li>

	<li>pošli článek k moderaci</li>

	<li>konec vlákna</li>
</ol>

<p>Vlákno 2:</p>

<ol>
	<li>vyber článek z fronty</li>

	<li>moderátor rozhodne, jestli akceptovat či odmítnout</li>

	<li>pokud moderátor akceptuje, zveřejni článek</li>

	<li>konec vlákna</li>
</ol>

<p>Jak budeme operace spouštět? Jak si zapamatovat, kde jsme v provádění
procesu skončili? Jak pak pokračovat v provádění existujícího procesu?
Jedna z možných odpovědí na tyto otázky je použít JBPM. Co JBPM
nabízí?</p>

<ul>
	<li>JBPM je nástroj pro spouštění business procesů.</li>

	<li>Pomocí jazyka JPDL (Jboss Process Definition Language) lze snadno a
	přehledně definovat graf procesu.</li>

	<li>Definice procesů lze verzovat. To v praxi znamená, že pokud změníme
	definici procesu, právě probíhající instance tohoto procesu to
	neovlivní.</li>

	<li>Jsou podporovány i takzvané wait-states, uzly ve kterých se provádění
	procesu zastaví.</li>

	<li>JBPM obsahuje podporu pro persistenci procesů. Stav právě
	probíhajících procesů je uložen v databázi.</li>

	<li>Instance procesu může používat procesní proměnné které jsou také
	ukládány spolu se stavem v databázi.</li>

	<li>Na přechody i na uzly lze navázat akce.</li>

	<li>Snadná integrace se Springem.</li>

	<li>Nástroj pro grafický návrh procesů.</li>
</ul>

<p>Nechci tady popisovat všechny vlastnosti JBPM ani JPDL, na stránkách Jboss
můžete najít výbornou dokumentaci. Dejme se tedy rovnou do implementace.</p>

<h3>Implementace</h3>

<p>Ukažme si, jak bude vypadat definice procesu moderace apriori v jazyce
JPDL, jednotlivé části si pak vysvětlíme:</p>

<pre
class="xml"><code>&lt;process-definition
    name="createArticle" xmlns="urn:jbpm.org:jpdl-3.2"&gt;

  &lt;start-state name="start state"&gt;
    &lt;transition to="create invisible article"/&gt;
  &lt;/start-state&gt;

  &lt;node name="create invisible article"&gt;
    &lt;event type="node-enter"&gt;
      &lt;action config-type="bean"
          class="blog.handler.CreateInvisibleArticle"&gt;
      &lt;/action&gt;
    &lt;/event&gt;
    &lt;transition to="send to moderation"/&gt;
  &lt;/node&gt;

  &lt;node name="send to moderation"&gt;
    &lt;event type="node-enter"&gt;
      &lt;action config-type="bean"
          class="blog.handler.SendToModeration"&gt;
      &lt;/action&gt;
    &lt;/event&gt;
    &lt;transition to="wait for moderation"/&gt;
  &lt;/node&gt;

  &lt;state name="wait for moderation"&gt;
    &lt;transition to="process decision"/&gt;
  &lt;/state&gt;

  &lt;decision name="process decision"&gt;
    &lt;transition to="make visible"&gt;
      &lt;condition&gt;#{decision.accept == true}&lt;/condition&gt;
    &lt;/transition&gt;
    &lt;transition to="end"&gt;
      &lt;condition&gt;#{decision.accept == false}&lt;/condition&gt;
    &lt;/transition&gt;
  &lt;/decision&gt;

  &lt;node name="make visible"&gt;
    &lt;event type="node-enter"&gt;
      &lt;action config-type="bean"
          class="blog.handler.MakeVisible"&gt;
      &lt;/action&gt;
    &lt;/event&gt;
    &lt;transition to="end"/&gt;
  &lt;/node&gt;

  &lt;end-state name="end" /&gt;

&lt;/process-definition&gt;</code></pre>

<p>Takže JPDL není nic jiného než XML které popisuje graf business procesu.
Vidíme, že se tento graf skládá z uzlů, přechodů a akcí. Speciálním
typem uzlu je stav. V našem procesu máme hned tři stavy: „start state“,
„wait for moderation“ a „end“. Provádění procesu, se v těchto
uzlech zastaví. Jak bude vypadat kód, který vytvoří novou instanci procesu
a spustí ji?</p>

<pre class="java"><code><span class="java-keywords1">public</span> <span
class="java-keywords1">void</span> createArticle(Article article) {
  JbpmContext context = jbpmConfiguration.createJbpmContext();
  <span
class="java-keywords1">try</span> {
    ProcessInstance instance = context.newProcessInstance(<span
class="java-quote">&quot;createArticle&quot;</span>);
    instance.getContextInstance().setTransientVariable(<span
class="java-quote">&quot;article&quot;</span>, article);
    instance.signal();
    System.out.prntln(<span
class="java-quote">&quot;stopped in state: &quot;</span>+instance.getRootToken().getNode()
        .getName());
  } <span
class="java-keywords1">finally</span> {
    context.close();
  }
}</code></pre>

<p>Zde již počítáme s tím že máme připravenou konfiguraci JBPM
v proměnné <code>jbpmConfiguration</code>. Nová instance procesu, kterou zde
vytváříme se nachází ve stavu „start state“. Akce, které se budou
v průběhu provádění instance procesu spouštět, budou potřebovat vědět
jaký článek vytváříme. Proto nastavíme proměnnou „article“. Tato
proměnná může být transientní, protože nepotřebujeme aby její hodnotu
JBPM ukládalo v databázi.</p>

<p>Zavoláním <code>instance.signal()</code> se spustí samotné provádění.
Provádění probíhá synchronně, tedy ve stejném vlákně a když se dostane
do prvního stavu, v našem případě „wait for moderation“, pak
probíhání skončí a tím i provádění metody <code>signal()</code>. Naše
metoda vypíše na standartní výstup řádek:</p>

<pre><code>stopped in state: wait for moderation</code></pre>

<p>Teď se podíváme, jak funguje spouštění akcí. Akci lze pověsit na
událost. V našem případě na událost typu „node-enter“. Akce musí
implementovat rozhraní <code>org.jbpm.graph.def.ActionHandler</code>. JBPM
vytvoří novou instanci třídy uvedené v atributu <code>class</code> tagu
<code>action</code> a zavolá metodu <code>execute</code>. Implementace třídy
<code>blog.handler.CreateInvisibleArticle</code> může vypadat
třeba takto:</p>

<pre class="java"><code><span
class="java-keywords1">package</span> blog.handler;

<span
class="java-keywords1">import</span> blog.Article;
<span
class="java-keywords1">import</span> org.jbpm.graph.def.ActionHandler;

<span
class="java-keywords1">public</span> <span
class="java-keywords1">class</span> CreateInvisibleArticle <span
class="java-keywords1">implements</span> ActionHandler {
    <span
class="java-keywords1">public</span> <span
class="java-keywords1">void</span> execute(ExecutionContext executionContext) <span
class="java-keywords1">throws</span> Exception {
        Article article = executionContext.getContextInstance()
            .getTransientVariable(<span
class="java-quote">&quot;article&quot;</span>);
        article.setVisible(false);
        getArticleDao().saveArticle(article);
    }
    ...
}</code></pre>

<p>Tato implementace počítá s tím, že instance procesu obsahuje
transientní proměnnou „article“ a jednoduše volá DAO vrstvu, aby
článek uložila. Jak bude naimplementovaná metoda
<code>getArticleDao()</code> není tématem tohoto článku. K tomuto problému
se vrátím v jíném článku, ve kterém se budu věnovat integraci JBPM se
Springem.</p>

<p>Podobně bude vypadat implementace <code>blog.handler.MakeVisible</code>:</p>

<pre class="java"><code><span
class="java-keywords1">package</span> blog.handler;

<span
class="java-keywords1">import</span> blog.Article;
<span
class="java-keywords1">import</span> org.jbpm.graph.def.ActionHandler;

<span
class="java-keywords1">public</span> <span
class="java-keywords1">class</span> MakeVisible <span
class="java-keywords1">implements</span> ActionHandler {
    <span
class="java-keywords1">public</span> <span
class="java-keywords1">void</span> execute(ExecutionContext executionContext) <span
class="java-keywords1">throws</span> Exception {
        Article article = executionContext.getContextInstance()
            .getTransientVariable(<span
class="java-quote">&quot;article&quot;</span>);
        article.setVisible(true);
        getArticleDao().updateArticle(article);
    }
    ...
}</code></pre>

<p>Zbývá nám poslední akce <code>blog.handler.SendToModeration</code>:</p>

<pre class="java"><code><span
class="java-keywords1">package</span> blog.handler;

<span
class="java-keywords1">import</span> blog.Article;
<span
class="java-keywords1">import</span> org.jbpm.graph.def.ActionHandler;

<span
class="java-keywords1">public</span> <span
class="java-keywords1">class</span> SendToModeration <span
class="java-keywords1">implements</span> ActionHandler {
    <span
class="java-keywords1">public</span> <span
class="java-keywords1">void</span> execute(ExecutionContext executionContext) <span
class="java-keywords1">throws</span> Exception {
        Article article = executionContext.getContextInstance()
            .getTransientVariable(<span
class="java-quote">&quot;article&quot;</span>);
        <span
class="java-keywords1">long</span> processInstanceId = executionContext.getProcessInstance().getId();
        getModerationQueue().add(article, processInstanceId);
    }
    ...
}</code></pre>

<p>Zajímavá je zde lokální proměnná <code>processInstanceId</code>,
k tomu abychom po moderátorově rozhodnutí mohli v provádění procesu
pokračovat, musíme vědět ke které instanci procesu se moderovaný článek
vztahuje. Proto do moderační fronty posíláme i id instance procesu. Toto id
pak využijeme pro získání existující instance procesu. Následující
metoda je zavolána když moderátor akceptuje článek:</p>

<pre class="java"><code>...
<span class="java-keywords1">public</span> <span
class="java-keywords1">void</span> acceptArticle(Article article, <span
class="java-keywords1">long</span> processInstanceId) {
  JbpmContext context = jbpmConfiguration.createJbpmContext();
  <span
class="java-keywords1">try</span> {
    ProcessInstance instance = context.getProcessInstance(processInstanceId);
    System.out.println(<span
class="java-quote">&quot;currently in state: &quot;</span>+instance.getRootToken().getNode()
        .getName());
    instance.getContextInstance().setTransientVariable(<span
class="java-quote">&quot;article&quot;</span>, article);
    Decision decision = <span
class="java-keywords1">new</span> Decision();
    decision.setAccept(true);
    instance.getContextInstance().setTransientVariable(<span
class="java-quote">&quot;decision&quot;</span>, decision);
    instance.signal();
    System.out.println(<span
class="java-quote">&quot;stopped in state: &quot;</span>+instance.getRootToken().getNode()
        .getName());
  } <span
class="java-keywords1">finally</span> {
    context.close();
  }
}
...</code></pre>

<p>Nejprve si vyžádáme instanci procesu podle processInstanceId, stejně jako
v metodě, <code>createArticle</code> musíme nastavit transientní proměnnou
„article“, aby další akce měly přístup k článku. Dále nastavíme
transientní proměnnou „decision“, která obsahuje informaci o tom, jak
moderátor rozhodl. Poté se zavolá metoda <code>signal()</code>, čímž dojde
k pokračování instance procesu. Metoda <code>acceptArticle</code> vypíše
na standardní výstup:</p>

<pre><code>currently in state: wait for moderation
stopped in state: end</code></pre>

<p>Proměnná <code>decision</code> se používá při rozhodování, který
přechod použít z uzlu „process decision“:</p>

<pre
class="xml"><code>&lt;decision name="process decision"&gt;
  &lt;transition to="make visible"&gt;
    &lt;condition&gt;#{decision.accept == true}&lt;/condition&gt;
  &lt;/transition&gt;
  &lt;transition to="end"&gt;
    &lt;condition&gt;#{decision.accept == false}&lt;/condition&gt;
  &lt;/transition&gt;
&lt;/decision&gt;</code></pre>

<p>JBPM v uzlu typu „decision“ vybere první přechod, jehož podmínka je
splněna. Pokud není žádná podmínka splněná, vybere se první definovaný
přechod.</p>

<h3>Závěr</h3>

<p>Viděli jste, jak jsme postupovali a jak a proč jsme se rozhodli pro JBPM.
Zatím to vypadá, že jsme zvolili správně. S dostatečně velikou množinou
akcí, lze pohou změnou definic procesů měnit chování našeho systému.</p>

<h3>Zdroje</h3>

<ul>
	<li><a href="http://docs.jboss.org/jbpm/v3/userguide/index.html">Oficiální
	dokumentace</a></li>
</ul>

<!-- by Texy2! -->]]></content:encoded>
			<wfw:commentRss>http://blog.itplace.cz/jak-jsme-pouzili-jbpm/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>

