<?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/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Xis' blog &#187; java</title>
	<atom:link href="http://xis.schowek.net/tag/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://xis.schowek.net</link>
	<description>Mój wirtualny schowek</description>
	<lastBuildDate>Thu, 10 Mar 2011 18:41:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>Upiększanie JTable</title>
		<link>http://xis.schowek.net/2009/03/11/upiekszanie-jtable/</link>
		<comments>http://xis.schowek.net/2009/03/11/upiekszanie-jtable/#comments</comments>
		<pubDate>Wed, 11 Mar 2009 11:15:32 +0000</pubDate>
		<dc:creator>xis</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jtable]]></category>
		<category><![CDATA[swing]]></category>

		<guid isPermaLink="false">http://xis.schowek.net/?p=289</guid>
		<description><![CDATA[Przy okazji moich zabaw ze Swingiem &#8211; krótko o tym jak ulepszyć JTable. Mamy sobie JTable taką: A będziemy chcieli taką: Wzbogacimy więc naszą tabelkę o bardzo ładne oznaczenie numerów wierszy, oraz kolorowanie co drugiego rekordu. Zabieg pierwszy: kolorowanie co drugiego wiersza Aby używać warunkowego kolorowania wierszy, musimy wskazać naszej tabelce, by wykorzystała obiekt klasy [...]]]></description>
			<content:encoded><![CDATA[<p>Przy okazji moich zabaw ze Swingiem &#8211; krótko o tym jak ulepszyć <a href="http://java.sun.com/javase/6/docs/api/javax/swing/JTable.html">JTable</a>.</p>
<p>Mamy sobie JTable taką:</p>
<p><img class="aligncenter size-full wp-image-290" title="przed" src="http://xis.schowek.net/wp-content/uploads/2009/03/przed.png" alt="przed" width="491" height="308" /></p>
<p>A będziemy chcieli taką:</p>
<p><img class="aligncenter size-full wp-image-294" title="po1" src="http://xis.schowek.net/wp-content/uploads/2009/03/po1.png" alt="po1" width="554" height="393" /></p>
<p>Wzbogacimy więc naszą tabelkę o bardzo ładne oznaczenie numerów wierszy, oraz kolorowanie co drugiego rekordu.</p>
<p><strong>Zabieg pierwszy: kolorowanie co drugiego wiersza</strong></p>
<p>Aby używać warunkowego kolorowania wierszy, musimy wskazać naszej tabelce, by wykorzystała obiekt klasy pochodnej od <a href="http://java.sun.com/javase/6/docs/api/javax/swing/table/DefaultTableCellRenderer.html">DefaultTableCellRenderer</a>, np. takiej:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> ColorCellRenderer <span style="color: #000000; font-weight: bold;">extends</span> <span style="color: #003399;">DefaultTableCellRenderer</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    @Override
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Component</span> getTableCellRendererComponent<span style="color: #009900;">&#40;</span> <span style="color: #003399;">JTable</span> table, <span style="color: #003399;">Object</span> val, <span style="color: #000066; font-weight: bold;">boolean</span> selected, <span style="color: #000066; font-weight: bold;">boolean</span> focused, <span style="color: #000066; font-weight: bold;">int</span> row, <span style="color: #000066; font-weight: bold;">int</span> col <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003399;">Component</span> comp <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">getTableCellRendererComponent</span><span style="color: #009900;">&#40;</span> table, val, selected, focused, row, col <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> selected <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">false</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span> row <span style="color: #339933;">%</span> <span style="color: #cc66cc;">2</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                comp.<span style="color: #006633;">setBackground</span><span style="color: #009900;">&#40;</span> color <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
            <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
                comp.<span style="color: #006633;">setBackground</span><span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">null</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">return</span> comp<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><strong>Zabieg drugi: numeracja wierszy</strong></p>
<p>Na forum Suna znalazłem b. stary, ale nadal ciekawy <a href="http://forums.sun.com/thread.jspa?messageID=3746961#3746961">przykład rozwiązania tego problemu</a>. Budujemy klasę <strong>LineNumberTable</strong>, która dziedziczy po JTable:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> LineNumberTable <span style="color: #000000; font-weight: bold;">extends</span> <span style="color: #003399;">JTable</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">JTable</span> mainTable<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> LineNumberTable<span style="color: #009900;">&#40;</span> <span style="color: #003399;">JTable</span> table <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        mainTable <span style="color: #339933;">=</span> table<span style="color: #339933;">;</span>
        setAutoCreateColumnsFromModel<span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">false</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        setModel<span style="color: #009900;">&#40;</span> mainTable.<span style="color: #006633;">getModel</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        setSelectionModel<span style="color: #009900;">&#40;</span> mainTable.<span style="color: #006633;">getSelectionModel</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        setAutoscrolls<span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">false</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        addColumn<span style="color: #009900;">&#40;</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">TableColumn</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        getColumnModel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getColumn</span><span style="color: #009900;">&#40;</span> <span style="color: #cc66cc;">0</span> <span style="color: #009900;">&#41;</span>.<span style="color: #006633;">setCellRenderer</span><span style="color: #009900;">&#40;</span> mainTable.<span style="color: #006633;">getTableHeader</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getDefaultRenderer</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        getColumnModel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getColumn</span><span style="color: #009900;">&#40;</span> <span style="color: #cc66cc;">0</span> <span style="color: #009900;">&#41;</span>.<span style="color: #006633;">setPreferredWidth</span><span style="color: #009900;">&#40;</span> <span style="color: #cc66cc;">30</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        setPreferredScrollableViewportSize<span style="color: #009900;">&#40;</span> getPreferredSize<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    @Override
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> isCellEditable<span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">int</span> row, <span style="color: #000066; font-weight: bold;">int</span> column <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    @Override
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Object</span> getValueAt<span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">int</span> row, <span style="color: #000066; font-weight: bold;">int</span> column <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Integer</span><span style="color: #009900;">&#40;</span> row <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    @Override
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">int</span> getRowHeight<span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">int</span> row <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> mainTable.<span style="color: #006633;">getRowHeight</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>OK, teraz wystarczy wykorzystać utworzone klasy w naszej JTable:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">    <span style="color: #000000; font-weight: bold;">public</span> MyPanel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        initComponents<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// wskazujemy nowy renderer, dla obiektów wszystkich typów naszej tabelki</span>
        jTable1.<span style="color: #006633;">setDefaultRenderer</span><span style="color: #009900;">&#40;</span> <span style="color: #003399;">Object</span>.<span style="color: #000000; font-weight: bold;">class</span>, <span style="color: #000000; font-weight: bold;">new</span> ColorCellRenderer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// scrollPane, którym mamy osadzoną tabelę dekorujemy oznaczeniem numerów wierszy</span>
        jScrollPane1.<span style="color: #006633;">setRowHeaderView</span><span style="color: #009900;">&#40;</span> <span style="color: #000000; font-weight: bold;">new</span> LineNumberTable<span style="color: #009900;">&#40;</span> jTable1 <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Gotowe. Prawda, że ładniej?</p>
]]></content:encoded>
			<wfw:commentRss>http://xis.schowek.net/2009/03/11/upiekszanie-jtable/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>NetBeans i ujednolicanie JDialog</title>
		<link>http://xis.schowek.net/2009/03/08/netbeans-i-ujednolicanie-jdialog/</link>
		<comments>http://xis.schowek.net/2009/03/08/netbeans-i-ujednolicanie-jdialog/#comments</comments>
		<pubDate>Sun, 08 Mar 2009 11:29:14 +0000</pubDate>
		<dc:creator>xis</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jdialog]]></category>
		<category><![CDATA[netbeans]]></category>
		<category><![CDATA[swing]]></category>

		<guid isPermaLink="false">http://xis.schowek.net/?p=242</guid>
		<description><![CDATA[Miałem niedawno okazję dłużej popracować nad projektami Javy w NetBeans 6.5 (wcześniej poważniej NetBeans używałem tylko do Grails). Środowisko to nie było dotychczas moim ulubionym, głównie ze względu na wydajność, co do której można mieć spore zastrzerzenia, jednak zauważyłem, że ma ono również mnóstwo zalet. Pierwszą jaką dostrzegłem jest to, że projekty generowane przez to [...]]]></description>
			<content:encoded><![CDATA[<p>Miałem niedawno okazję dłużej popracować nad projektami Javy w <a href="http://www.netbeans.org/">NetBeans 6.5</a> (wcześniej poważniej NetBeans używałem tylko do <a href="http://www.grails.org/">Grails</a>). Środowisko to nie było dotychczas moim ulubionym, głównie ze względu na wydajność, co do której można mieć spore zastrzerzenia, jednak zauważyłem, że ma ono również mnóstwo zalet. Pierwszą jaką dostrzegłem jest to, że projekty generowane przez to <em>IDE</em> są naprawdę ładnie utworzone, wykorzystują standardowe narzędzia Javy, takie jak np. <a href="http://www.ant.apache.org/">Ant</a> i nie uzależniają użytkownika od używania &#8222;jedynego i właściwego&#8221; IDE. NetBeans może zauroczyć również stopniem dopracowania swoich elementów &#8211; jak już coś wspiera, to wspiera naprawdę dobrze. Przykładem tu może być sposób, w jaki można za pomocą tego środowiska utworzyć i zarządzać aplkacjami wykorzystującymi <em>Web Services</em> w aplikacji &#8211; zarówno klientem, jak i usługą wykorzystującącymi <em>API</em> <a href="http://en.wikipedia.org/wiki/JAX-WS">JAX-WS</a>. Kolejny (lecz na pewno nie ostatni) plus należy się NetBeans za właściwie bezkonkurencyjny <em>edytor wizualny</em> aplikacji wykorzystujących <a href="http://pl.wikipedia.org/wiki/Swing_(Java)">Swing</a>.</p>
<p>I o Swingu właśnie będzie ten wpis (nieco przydługi, ostrzegam).</p>
<p>Nie do końca podoba mi się domyślna filozofia <em>okien dialogowych</em> w Javie. Np. rozmiar &#8211; niby można zmieniać rozmiar &#8222;świeżo&#8221; utworzonego okienka dialogowego rozciągając je, ale menadżery okien nie pozwalają na jego maksymalizację (brakuje bowiem przycisku maksymalizacji). Wiem, że takie jest założenie okienek dialogowych, ale wyczuwam tu pewną niekonsekwencję. Ponadto &#8222;goły&#8221; <a href="http://java.sun.com/javase/6/docs/api/javax/swing/JDialog.html">JDialog</a> jest praktycznie pozbawiony funkcjonalności, np. brakuje mu domyślnych zachowań takich jak potwierdzanie i anulowanie, reakcję na przycisk <em>Escape</em> i <em>Enter</em> &#8211; te braki sprawiają, że każda implementacja okienka dialogowego musi być poprzedzona żmudnym wykonywaniem tych banalnych czynności.</p>
<p>Postanowiłem więc wykonać coś na wzór <em>bazy</em> dla okna dialogowego, która to baza będzie wyposażona we wszystkie cechy, które wg mnie posiadać powinna każda implementacja JDialog. W takiej bazie będę umieszczał różne komponenty &#8211; w zależności od tego, jakiego dialogu potrzebuję.</p>
<p><img class="size-full wp-image-243" style="margin: 0; margin-left: -25px;" title="szkic" src="http://xis.schowek.net/wp-content/uploads/2009/03/szkic.png" alt="szkic" width="689" height="440" /></p>
<p>Chcę uzyskać bazę dla dialogu, w której będę umieszczał przeróżne panele &#8211; począwszy od prostych, informacyjnych (wtedy taki dialog przypominałby funkconalnością <a href="http://java.sun.com/javase/6/docs/api/javax/swing/JOptionPane.html">JOptionPane</a>), skończywszy na całkiem zaawansowanych funkcjonalnie formularzach edycji wykorzystujących panele, które przygotuję sobie osobno (dzięki temu będę mógł wykorzystać panele także w innych sytuacjach). Wszystkie jednak dialogi cechować się mają wspólnymi właściwościami: dialog można zatwierdzić (<em>submit</em>), albo odrzucić (<em>cancel</em>). Wciśnięcie <em>Escape</em> na aktywnym oknie powoduje jego zamknięcie (funkcjonalność identyczna do wciśnięcia przycisku <em>Anuluj</em>), a <em>Enter</em> &#8211; zatwierdzenie (kliknięcie <em>OK</em>).</p>
<p>W tym celu zbudowałem JDialog w NetBeans wybierając z menu projektu <strong>New</strong>-&gt;<strong>JDialog Form</strong> i nazwałem go <strong>DialogBase</strong>. W edytorze wizualnym umieściłem dwa przyciski (nazwałem je <strong>jBtnOK</strong> i <strong>jBtnCancel</strong>), oraz jeden <a href="http://java.sun.com/javase/6/docs/api/javax/swing/JPanel.html">JPane</a>l (<strong>jPanelMain</strong>), z ustawionym layoutem <a href="http://java.sun.com/javase/6/docs/api/java/awt/BorderLayout.html">BorderLayout</a> &#8211; w tym panelu będę umieszczał przeróżne panele &#8222;implementacyjne&#8221; &#8211; w zależności od przeznaczenia mojego dialogu.</p>
<p>Na początek, domyślny konstruktor i obsługa własności <strong>panel</strong> (czyli obiekt panelu, który umieszczamy w oknie):</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">JPanel</span> panel<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> DialogBase<span style="color: #009900;">&#40;</span><span style="color: #003399;">JPanel</span> panel<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span><span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">null</span>, <span style="color: #000066; font-weight: bold;">true</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        setLocationRelativeTo<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        setPanel<span style="color: #009900;">&#40;</span>panel<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> setPanel<span style="color: #009900;">&#40;</span><span style="color: #003399;">JPanel</span> panel<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">panel</span> <span style="color: #339933;">=</span> panel<span style="color: #339933;">;</span>
        jPanelMain.<span style="color: #006633;">removeAll</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        jPanelMain.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span> panel, <span style="color: #003399;">BorderLayout</span>.<span style="color: #006633;">CENTER</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        panel.<span style="color: #006633;">setVisible</span><span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">true</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #003399;">Dimension</span> d <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Dimension</span><span style="color: #009900;">&#40;</span>panel.<span style="color: #006633;">getPreferredSize</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">setSize</span><span style="color: #009900;">&#40;</span> d.<span style="color: #006633;">width</span>, d.<span style="color: #006633;">height</span><span style="color: #339933;">+</span><span style="color: #cc66cc;">70</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #003399;">JPanel</span> getPanel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> panel<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Metoda <strong>setPanel()</strong> ustawia własność <strong>panel</strong> oraz zajmuje się osadzeniem go w oknie dialogu i ustawieniem odpowiedniego rozmiaru okna (wysokość zwiększam o wielkość przycisków na dole okna).</p>
<p>Aby wiedzieć w jaki sposób moje okno dialogowe zostało zamknięte, wyposażam je we własność <strong>exitStatus</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> DLG_EXIT_CANCEL <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> DLG_EXIT_OK <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">int</span> exitStatus <span style="color: #339933;">=</span> DLG_EXIT_CANCEL<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// getter i setter</span></pre></div></div>

<p>Domyślne zamknięcie okna poskutkuje zapamiętaniem statusu &#8222;Cancel&#8221;.</p>
<p>Czas na obsługę klawisza <em>Escape</em> i <em>Enter</em>. Posiłkując się <a href="http://www.javaworld.com/javaworld/javatips/jw-javatip72.html?page=1">ciekawym na ten temat artykułem</a>, wzbogaciłem mój <strong>DialogBase</strong> o następujący kod:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">    @Override
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #003399;">JRootPane</span> createRootPane<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003399;">JRootPane</span> theRootPane <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">JRootPane</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #003399;">KeyStroke</span> escStroke <span style="color: #339933;">=</span> <span style="color: #003399;">KeyStroke</span>.<span style="color: #006633;">getKeyStroke</span><span style="color: #009900;">&#40;</span> <span style="color: #003399;">KeyEvent</span>.<span style="color: #006633;">VK_ESCAPE</span>, <span style="color: #cc66cc;">0</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        theRootPane.<span style="color: #006633;">registerKeyboardAction</span><span style="color: #009900;">&#40;</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">ActionListener</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> actionPerformed<span style="color: #009900;">&#40;</span> <span style="color: #003399;">ActionEvent</span> actionEvent <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                doCancel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>, escStroke, <span style="color: #003399;">JComponent</span>.<span style="color: #006633;">WHEN_IN_FOCUSED_WINDOW</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #003399;">KeyStroke</span> entStroke <span style="color: #339933;">=</span> <span style="color: #003399;">KeyStroke</span>.<span style="color: #006633;">getKeyStroke</span><span style="color: #009900;">&#40;</span> <span style="color: #003399;">KeyEvent</span>.<span style="color: #006633;">VK_ENTER</span>, <span style="color: #cc66cc;">0</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        theRootPane.<span style="color: #006633;">registerKeyboardAction</span><span style="color: #009900;">&#40;</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">ActionListener</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> actionPerformed<span style="color: #009900;">&#40;</span> <span style="color: #003399;">ActionEvent</span> actionEvent <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                doSubmit<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>, entStroke, <span style="color: #003399;">JComponent</span>.<span style="color: #006633;">WHEN_IN_FOCUSED_WINDOW</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">return</span> theRootPane<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Jak widzisz, wykorzystuję tu tajemnicze metody <strong>doSubmit()</strong> i <strong>doCancel()</strong>. Co to za metody?</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">void</span> doSubmit<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> onSubmit<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            setExitStatus<span style="color: #009900;">&#40;</span> DLG_EXIT_OK <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            dispose<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">void</span> doCancel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> onCancel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            setExitStatus<span style="color: #009900;">&#40;</span> DLG_EXIT_CANCEL <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            dispose<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">boolean</span> onSubmit<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">boolean</span> onCancel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Obie metody działają dość podobnie: jeśli metoda <strong>onSubmit()</strong> (lub analogicznie <strong>onCancel()</strong>) zwróci <strong>true</strong>, ustawiamy odpowiedni <strong>exitStatus</strong> i zamykamy okno. Zarówno <strong>doSubmit()</strong> jak i <strong>doCancel()</strong> wiążę też za pomocą zdarzenia <a href="http://java.sun.com/javase/6/docs/api/java/awt/event/ActionEvent.html">ActionEvent</a> z przyciskami (wystarczy dwukrotnie kliknąć na przycisku w edytorze wizualnym i wyedytować wygenerowaną przez NetBeans pustą metodę):</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">void</span> jBtnCancelActionPerformed<span style="color: #009900;">&#40;</span>java.<span style="color: #006633;">awt</span>.<span style="color: #006633;">event</span>.<span style="color: #003399;">ActionEvent</span> evt<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        doCancel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">void</span> jBtnOKActionPerformed<span style="color: #009900;">&#40;</span>java.<span style="color: #006633;">awt</span>.<span style="color: #006633;">event</span>.<span style="color: #003399;">ActionEvent</span> evt<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        doSubmit<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<p>OK, ale po co nam te trywialne metody <strong>onSubmit()</strong> i <strong>onCancel()</strong>? Wykorzystamy je np. do walidacji w przyszłych implementacjach naszych okien dialogowych (jeśli zdecydujemy się na ich przesłonięcie, jeśli nie &#8211; niczego złego nie zrobią ;) ).</p>
<p>Wygląda na to, że nasza baza jest gotowa. Użyjmy jej więc na jakimś przykładzie &#8211; np. formularzu logowania.</p>
<p>W NetBeans, tworzymy nowy <strong>JPanel Form</strong>, nazywamy go <strong>PanelLogin</strong> i dodajemy odpowiednie elementy interfejsu użytkownika (jak na załączonym wyżej szkicu), oczywiście to ten panel będziemy osadzać w bazie dialogu, więc nie dodajemy już przycisków <em>OK</em> i <em>Anuluj</em>, bo nie musimy. Element <a href="http://java.sun.com/javase/6/docs/api/javax/swing/JTextField.html">JTextField</a>, zawierający nazwę użytkownika nazywamy <strong>jTxtUsername</strong>, a <a href="http://java.sun.com/javase/6/docs/api/javax/swing/JPasswordField.html">JPasswordField</a> (z hasłem) &#8211; <strong>jTxtPassword</strong>.<br />
Dodajemy dwie publiczne metody do pobrania wprowadzonych nazwy użytkownika i hasła:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getUsername<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> jTxtUsername.<span style="color: #006633;">getText</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getPassword<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">String</span><span style="color: #009900;">&#40;</span>jTxtPassword.<span style="color: #006633;">getPassword</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<p>A teraz nasz dialog logowania.<br />
W NetBeans tworzę nową <span style="text-decoration: underline;">klasę Javy</span> (<strong>New</strong>-&gt;<strong>Java Class</strong>), a nie dialog(!) i nazywam ją <strong>DialogLogin</strong>. Nasza nowa klasa musi dziedziczyć po <strong>DialogBase</strong>. Ponadto, nasz dialog powinien zwracać obiekt użytkownika (jakiejś klasy np. <strong>User</strong>, której szczegóły nie są tu istotne) jeśli logowanie się powiedzie. W tym celu powołujemy własność <strong>returnValue</strong> (wraz z getterem i setterem). Przy okazji dodaję też licznik prób logowania &#8211; proste umożliwienie trzykrotnej pomyłki przy logowaniu.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> DialogLogin <span style="color: #000000; font-weight: bold;">extends</span> DialogBase <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">private</span> User returnValue<span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">int</span> tries <span style="color: #339933;">=</span> <span style="color: #cc66cc;">3</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> DialogLogin<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> PanelLogin<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Czas na obsługę logiki biznesowej naszego dialogu. Anulowanie dialogu zostawiamy bez zmian &#8211; po prostu zamykamy okno. Jednak musimy zaimplementować obsługę zatwierdzania formularza. W tym celu przesłaniamy naszą metodę <strong>onSubmit()</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">    @Override
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">boolean</span> onSubmit<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        PanelLogin thePanel <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span> PanelLogin <span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">getPanel</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        User u <span style="color: #339933;">=</span> App.<span style="color: #006633;">login</span><span style="color: #009900;">&#40;</span> thePanel.<span style="color: #006633;">getUsername</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, thePanel.<span style="color: #006633;">getPassword</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> u <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #003399;">JOptionPane</span>.<span style="color: #006633;">showMessageDialog</span><span style="color: #009900;">&#40;</span> <span style="color: #000000; font-weight: bold;">this</span>, <span style="color: #0000ff;">&quot;Nie udało się zalogować&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">--</span>tries<span style="color: #339933;">&lt;=</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        returnValue <span style="color: #339933;">=</span> u<span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Jeśli <strong>App.login()</strong> (przyjmijmy, że ta metoda odpowiada za autoryzację aplikacji) zwróci <strong>null</strong>, to znaczy, ze nie zalogowaliśmy się do aplikacji &#8211; dialog nie zamknie się, ale pokaże nam info o nieprawidłowych parametrach logowania (i tak do momentu aż wartość <strong>tries</strong> osiągnie wartość mniejszą lub równą zeru). Jeśli użytkownik jest prawidłowy, dialog zamknie się ustawiwszy uprzednio własność <strong>returnValue</strong>.</p>
<p>Powinno działać. Sprawdźmy:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #003399;">UIManager</span>.<span style="color: #006633;">setLookAndFeel</span><span style="color: #009900;">&#40;</span> <span style="color: #003399;">UIManager</span>.<span style="color: #006633;">getSystemLookAndFeelClassName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">catch</span><span style="color: #009900;">&#40;</span> <span style="color: #003399;">Exception</span> ex <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
&nbsp;
        DlgLogin dlg <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DlgLogin<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        dlg.<span style="color: #006633;">setVisible</span><span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">true</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #003399;">System</span>.<span style="color: #006633;">err</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Logowanie zakończone: &quot;</span><span style="color: #339933;">+</span>dlg.<span style="color: #006633;">getExitStatus</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> dlg.<span style="color: #006633;">getExitStatus</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> DialogBase.<span style="color: #006633;">DLG_EXIT_OK</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> dlg.<span style="color: #006633;">getReturnValue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #003399;">System</span>.<span style="color: #006633;">err</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;W porządku, użytkownik prawidłowy&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
            <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #003399;">System</span>.<span style="color: #006633;">err</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Brak dostępu!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #003399;">System</span>.<span style="color: #006633;">err</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Anulowano!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Voila!</p>
<p><em>We wpisie użyłem ikon <a href="http://kde-look.org/content/show.php/Free+Business+Icons?content=77050  ">Free Business Icons</a> opublikowanych na licencji <a href="http://creativecommons.org/licenses/by/3.0/deed.pl  ">Creative Commons</a> oraz <a href="http://www.famfamfam.com/lab/icons/silk/">Silk</a> na licencji <a href="http://www.gnu.org/licenses/lgpl-3.0-standalone.html">LGPL</a>.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://xis.schowek.net/2009/03/08/netbeans-i-ujednolicanie-jdialog/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Grails i kompozytowe klucze w Hibernate</title>
		<link>http://xis.schowek.net/2009/01/24/grails-i-kompozytowe-klucze-w-hibernate/</link>
		<comments>http://xis.schowek.net/2009/01/24/grails-i-kompozytowe-klucze-w-hibernate/#comments</comments>
		<pubDate>Sat, 24 Jan 2009 16:30:06 +0000</pubDate>
		<dc:creator>xis</dc:creator>
				<category><![CDATA[Do zapamiętania]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[orm]]></category>

		<guid isPermaLink="false">http://xis.schowek.net/?p=202</guid>
		<description><![CDATA[Grails to bardzo ciekawy framework przygotowany dla języka Groovy. Od razu zdobył moją sympatię za to, że &#8211; nie tylko nazwą &#8211; przypomina architekturę Ruby on Rails, czy też Symfony dla PHP, realizując najważniejsze polityki nowoczesnych frameworków: Convention Over Configuration i Do Not Repeat Yourself. Zawsze ubolewałem (i w sumie nadal ubolewam) nad brakiem takiego [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://grails.org/">Grails</a> to bardzo ciekawy framework przygotowany dla języka <a href="http://groovy.codehaus.org/">Groovy</a>. Od razu zdobył moją sympatię za to, że &#8211; nie tylko nazwą &#8211; przypomina architekturę <a href="http://rubyonrails.org/">Ruby on Rails</a>, czy też <a href="http://www.symfony-project.org/">Symfony</a> dla <a href="http://php.net">PHP</a>, realizując najważniejsze polityki nowoczesnych frameworków: <a href="http://en.wikipedia.org/wiki/Convention_over_Configuration">Convention Over Configuration</a> i <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">Do Not Repeat Yourself</a>. Zawsze ubolewałem (i w sumie nadal ubolewam) nad brakiem takiego rozwiązania dla &#8216;czystej&#8217; Javy (może Ty znasz jakiś przykład?), dlatego tym chętniej zainteresowałem się tajnikami Grails.</p>
<p>Przyznam, że raczej sceptycznie reaguję na różne &#8216;liberalne&#8217; języki programowania, np. fakt, że jakąś operację można wykonać używając różnych konstrukcji języka (bo wg mnie zaciemnia to nieco obraz samego kodu i utrudnia jego pielęgnację), albo dynamiczcne typowanie (zawsze przeklinałem PHP za tę &#8216;przypadłość&#8217;), jednak dałem Groovy&#8217;emu szansę, za jego główną zaletę: pełną kompatybilność z Javą &#8211; Groovy jest de facto wykonywany przez maszynę wirtualną Javy, więc kompatybilność ta jest oczywista.</p>
<p>Umówmy się &#8211; należę do tych bardziej konserwatywnych programistów wierzących w &#8216;twardą&#8217; składnię, a w Groovy nie umiem (jeszcze) nic poza &#8222;Hello World&#8221;, toteż bardzo zależało mi na frameworku, w którym będę mógł wykorzystać już istniejące ziarenka Javy.  Samego Groovy&#8217;ego też chętnie zgłębię, ale najpierw chcę zobaczyć co mogę zrobić z Grailsami wykorzystując istniejący już kod Javy.</p>
<p>Grails &#8211; jak RoR, czy Symfony &#8211; posiada własny mechanizm <a href="http://en.wikipedia.org/wiki/Object-relational_mapping">mapowania obiektowo-relacyjnego</a> (gdzieś tam głęboko napędzany przez <a href="http://www.hibernate.org/">Hibernate</a>), zwany <a href="http://grails.org/GORM">GORM</a>, pozwalający na mapowanie klas Groovy&#8217;ego z bazą danych. Ja jednak, przez założenie, chcę mapować ziarna encji Hibernate napisane w Javie. Grails pozwala na to bez problemów, kilka prostych czynności i już możemy wykorzystać przygotowane wcześniej encje w Grails.</p>
<p>No, może nie całkiem bez problemów.</p>
<p>Aby zmapować klasy encji wystarczy, zgodnie z <a href="http://grails.org/Hibernate+Integration">opisem na stronie Grails</a>, wyedytować plik <strong>DataSource.groovy</strong>, dodać mapowanie w <strong>hibernate.cfg.xml</strong> i wreszcie skopiować swoje klasy javy do katalogu <strong>src/java</strong>. Po wykonaniu tych czynności możemy już wygenerować na podstawie encji nowy kontroler i widok, wklepując w konsoli:</p>
<pre>grails generate-all pelna.nazwa.naszej.Klasy</pre>
<p>Grails wygeneruje dla nas wszystkie niezbędne klasy kontrolerów (w języku Groovy, rzecz jasna), elementy widoku (strony GSP), słowem mamy już cały <a href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete">CRUD</a>.  Problem jednak pojawia się w przypadku, gdy nasza encja wyposażona jest w klucz złożony, a schemat naszej bazy danych &#8211; jak w moim przypadku &#8211;  nie może zostać zmodyfikowany, bo jest wykorzystywany przez inne programy.</p>
<p>Grails teoretycznie pozwoli na mapowanie takich encji, wygeneruje też dla nich kontrolery i pliki widoków, jednak nie bedą one działały. Rozważmy poniższy przypadek.</p>
<p>Mamy encję Produkt (mapowaną  na tabelę &#8222;PRODUKTY&#8221;), encję Cennik (mapowaną na tabelę &#8222;CENNIKI&#8221;) i encję Cena (tabela &#8222;CENY&#8221;) .  <a href="http://www.netbeans.org/">NetBeans</a>, na podstawie istniejącego schematu bazy danych, wygenerował mi takie klasy (po drobnej korekcie nazw własności):</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">net.schowek.grailsapp</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// importy</span>
&nbsp;
@<span style="color: #003399;">Entity</span>
@Table<span style="color: #009900;">&#40;</span>name <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;PRODUKTY&quot;</span><span style="color: #009900;">&#41;</span>
@NamedQueries<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>@NamedQuery<span style="color: #009900;">&#40;</span>name <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;Produkt.findAll&quot;</span>, query <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;SELECT p FROM Produkt p&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Produkt <span style="color: #000000; font-weight: bold;">implements</span> <span style="color: #003399;">Serializable</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">long</span> serialVersionUID <span style="color: #339933;">=</span> 1L<span style="color: #339933;">;</span>
&nbsp;
    @Id
    @Basic<span style="color: #009900;">&#40;</span>optional <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span>
    @Column<span style="color: #009900;">&#40;</span>name <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;pr_id&quot;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Integer</span> id<span style="color: #339933;">;</span>
&nbsp;
    @Basic<span style="color: #009900;">&#40;</span>optional <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span>
    @Column<span style="color: #009900;">&#40;</span>name <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;pr_nazwa&quot;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> nazwa<span style="color: #339933;">;</span>
&nbsp;
    @Column<span style="color: #009900;">&#40;</span>name <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;pr_opis&quot;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> opis<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> Produkt<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> Produkt<span style="color: #009900;">&#40;</span><span style="color: #003399;">Integer</span> prId<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">id</span> <span style="color: #339933;">=</span> prId<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// gettery i settery</span>
&nbsp;
    @Override
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> toString<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> getNazwa<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">net.schowek.grailsapp</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// importy</span>
&nbsp;
@<span style="color: #003399;">Entity</span>
@Table<span style="color: #009900;">&#40;</span>name <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;CENNIKI&quot;</span><span style="color: #009900;">&#41;</span>
@NamedQueries<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>@NamedQuery<span style="color: #009900;">&#40;</span>name <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;Cennik.findAll&quot;</span>, query <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;SELECT c FROM Cennik c&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Cennik <span style="color: #000000; font-weight: bold;">implements</span> <span style="color: #003399;">Serializable</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">long</span> serialVersionUID <span style="color: #339933;">=</span> 1L<span style="color: #339933;">;</span>
&nbsp;
    @Id
    @Basic<span style="color: #009900;">&#40;</span>optional <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span>
    @Column<span style="color: #009900;">&#40;</span>name <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;cn_id&quot;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Integer</span> id<span style="color: #339933;">;</span>
&nbsp;
    @Column<span style="color: #009900;">&#40;</span>name <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;cn_nazwa&quot;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> nazwa<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> Cennik<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> Cennik<span style="color: #009900;">&#40;</span><span style="color: #003399;">Integer</span> cnId<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">id</span> <span style="color: #339933;">=</span> cnId<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// gettery i settery</span>
&nbsp;
    @Override
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> toString<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> getNazwa<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">net.schowek.grailsapp</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// importy</span>
&nbsp;
@<span style="color: #003399;">Entity</span>
@Table<span style="color: #009900;">&#40;</span>name <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;CENY&quot;</span><span style="color: #009900;">&#41;</span>
@NamedQueries<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>@NamedQuery<span style="color: #009900;">&#40;</span>name <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;Cena.findAll&quot;</span>, query <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;SELECT c FROM Cena c&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Cena <span style="color: #000000; font-weight: bold;">implements</span> <span style="color: #003399;">Serializable</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">long</span> serialVersionUID <span style="color: #339933;">=</span> 1L<span style="color: #339933;">;</span>
&nbsp;
    @EmbeddedId
    <span style="color: #000000; font-weight: bold;">private</span> CenaPK id<span style="color: #339933;">;</span>
&nbsp;
    @JoinColumn<span style="color: #009900;">&#40;</span> name <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;ce_pr_id&quot;</span>, referencedColumnName <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;pr_id&quot;</span>, insertable <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span>, updatable <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span>  <span style="color: #009900;">&#41;</span>
    @ManyToOne
    <span style="color: #000000; font-weight: bold;">private</span> Produkt produkt<span style="color: #339933;">;</span>
&nbsp;
    @JoinColumn<span style="color: #009900;">&#40;</span> name <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;ce_cn_id&quot;</span>, referencedColumnName <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;cn_id&quot;</span>, insertable <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span>, updatable <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span>  <span style="color: #009900;">&#41;</span>
    @ManyToOne
    <span style="color: #000000; font-weight: bold;">private</span> Cennik cennik<span style="color: #339933;">;</span>
&nbsp;
    @Column<span style="color: #009900;">&#40;</span>name <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;ce_cena&quot;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">BigDecimal</span> cena<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> Cena<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> Cena<span style="color: #009900;">&#40;</span>CenaPK cenaPK<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">id</span> <span style="color: #339933;">=</span> cenaPK<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// gettery i settery</span>
&nbsp;
    @Override
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> toString<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> getId<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>I wreszcie klasa określająca nasz klucz złożony:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">net.schowek.grailsapp</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// importy</span>
&nbsp;
@Embeddable
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> CenaPK <span style="color: #000000; font-weight: bold;">implements</span> <span style="color: #003399;">Serializable</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    @Basic<span style="color: #009900;">&#40;</span>optional <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span>
    @Column<span style="color: #009900;">&#40;</span>name <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;ce_pr_id&quot;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">int</span> cePrId<span style="color: #339933;">;</span>
&nbsp;
    @Basic<span style="color: #009900;">&#40;</span>optional <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span>
    @Column<span style="color: #009900;">&#40;</span>name <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;ce_cn_id&quot;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">int</span> ceCnId<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> CenaPK<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> CenaPK<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> cePrId, <span style="color: #000066; font-weight: bold;">int</span> ceCnId<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">cePrId</span> <span style="color: #339933;">=</span> cePrId<span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">ceCnId</span> <span style="color: #339933;">=</span> ceCnId<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">int</span> getCePrId<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> cePrId<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setCePrId<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> cePrId<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">cePrId</span> <span style="color: #339933;">=</span> cePrId<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">int</span> getCeCnId<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> ceCnId<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setCeCnId<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> ceCnId<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">ceCnId</span> <span style="color: #339933;">=</span> ceCnId<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    @Override
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> toString<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #0000ff;">&quot;net.schowek.grailsapp.CenaPK[cePrId=&quot;</span> <span style="color: #339933;">+</span> cePrId <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;, ceCnId=&quot;</span> <span style="color: #339933;">+</span> ceCnId <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;]&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Tak przygotowanesą podstawą wygenerowanej aplikacji.  Po uruchomieniu aplikacji za pomocą komendy grails run-app mogę już eksplorować zasoby cen i produktów. Problem jednak zaczyna się, gdy chcę przejrzeć listę cen. Już na liście (http://localhost:8080/GrailsApp/cena/list) widać, że odnośniki do rekordów cen nie przypominają standardowych odnośników do rekordów tabel o prostych kluczach. Przykładowy link do ceny wyglądał tak:</p>
<p><a href="http://localhost:8080/GrailsAppl/cena/show/net.schowek.grailsapp.CenaPK%5BcePrId%3D63%2C+ceCnId%3D2%5D">http://localhost:8080/GrailsAppl/cena/show/net.schowek.grailsapp.CenaPK%5BcePrId%3D63%2C+ceCnId%3D2%5D</a></p>
<p>a strona, którą można pod nim zobaczyć wygląda tak:</p>
<p><img class="aligncenter size-full wp-image-211" title="err" src="http://xis.schowek.net/wp-content/uploads/2009/01/err.jpg" alt="err" width="770" height="407" /><br />
Jak widać, Grails w miejsce <strong>id</strong>, podstawia wartość obiektu klasy <strong>CenaPK</strong>, a ten reprezentowany jest przez swoją metodę <strong>toString()</strong>.  Po odwołaniu się do serwera i zapytaniu o cenę o podanym kluczu, serwer &#8211; co oczywiste &#8211; częstuje nas wyjątkiem.</p>
<p>Oto prosty sposób, w jaki można temu zaradzić (zakładając, że klucz złożony składa się z pól typu numerycznego).</p>
<p>Przede wszystkim, zmieniłem kod klasy <strong>CenaPK</strong> na taki (zmieniłem <strong>toString() </strong>i dodałem jeden konstruktor):</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> KEY_SEPARATOR<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;_&quot;</span><span style="color: #339933;">;</span>
&nbsp;
    @Override
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> toString<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> cePrId<span style="color: #339933;">+</span>KEY_SEPARATOR<span style="color: #339933;">+</span>ceCnId<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> CenaPK<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> k<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> keys <span style="color: #339933;">=</span> k.<span style="color: #006633;">split</span><span style="color: #009900;">&#40;</span> KEY_SEPARATOR <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">cePrId</span> <span style="color: #339933;">=</span> <span style="color: #003399;">Integer</span>.<span style="color: #006633;">parseInt</span><span style="color: #009900;">&#40;</span>keys<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">ceCnId</span> <span style="color: #339933;">=</span> <span style="color: #003399;">Integer</span>.<span style="color: #006633;">parseInt</span><span style="color: #009900;">&#40;</span>keys<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Jak widzisz, połączyłem w jeden string dwa klucze oddzielone od siebie separatorem. Oznacza to, że ponowne wygenerowanie widoków komendą:</p>
<pre>grails generate-views net.schowek.grailsapp.Cena</pre>
<p>poskutkuje nową listą cen, zawierającą odnośniki do rekordów podobne do tych:</p>
<p><a href="http://localhost:8080/GrailsAppl/cena/show/63_2">http://localhost:8080/GrailsAppl/cena/show/63_2</a></p>
<p>Aby wszystko grało, musiałem jeszcze przerobić kontroler cen (plik <strong>CenaController.groovy</strong> w katalogu <strong>controllers/</strong>) i zmienić wszystkie linie ładujące pojedynczy rekord ceny z</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">def</span> cenaInstance <span style="color: #66cc66;">=</span> Cena.<span style="color: #663399;">get</span><span style="color: #66cc66;">&#40;</span> params.<span style="color: #006600;">id</span> <span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>na</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">def</span> cenaInstance <span style="color: #66cc66;">=</span> Cena.<span style="color: #663399;">get</span><span style="color: #66cc66;">&#40;</span> <span style="color: #000000; font-weight: bold;">new</span> CenaPK<span style="color: #66cc66;">&#40;</span>params.<span style="color: #006600;">id</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Od tej pory mogłem się już cieszyć działającą aplikacją obsługującą klucze złożone.</p>
<p>Aha, separatorem klucza może być w zasadzie dowolny znak, jednak są tu wyjątki &#8211; np. nie zadziała na pewno <em>slash</em>, ponieważ jest on interpretowany przez <strong>UrlMappera</strong> grails. Warto zatem sprawdzić co zadziała, a co nie.</p>
]]></content:encoded>
			<wfw:commentRss>http://xis.schowek.net/2009/01/24/grails-i-kompozytowe-klucze-w-hibernate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hojna Gwiazdka</title>
		<link>http://xis.schowek.net/2008/12/25/hojna-gwiazdka/</link>
		<comments>http://xis.schowek.net/2008/12/25/hojna-gwiazdka/#comments</comments>
		<pubDate>Thu, 25 Dec 2008 11:05:24 +0000</pubDate>
		<dc:creator>xis</dc:creator>
				<category><![CDATA[Ogólnie]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[EJB]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[j2ee]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[junit]]></category>
		<category><![CDATA[święta]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[wtp]]></category>
		<category><![CDATA[xis]]></category>

		<guid isPermaLink="false">http://xis.schowek.net/?p=162</guid>
		<description><![CDATA[Tegoroczna Gwiazdka była dla mnie, jako programisty, niesamowicie obfita. Pod choinką znalazłem stos świetnych pozycji dotyczących ogólnie Javy, ale i jej poszczególnych technologii. I tak, dostało mi się: JUnit &#8211; Pragmatyczne testy jednostkowe w Javie JAVA &#8211; Tworzenie aplikacji sieciowych za pomocą Springa, Hibernate i Eclipse Eclipse Web Tools Platform &#8211; Tworzenie aplikacji WWW w [...]]]></description>
			<content:encoded><![CDATA[<p>Tegoroczna Gwiazdka była dla mnie, jako programisty, niesamowicie obfita. Pod choinką znalazłem stos świetnych pozycji dotyczących ogólnie Javy, ale i jej poszczególnych technologii. I tak, dostało mi się:</p>
<ul>
<li>JUnit &#8211; Pragmatyczne testy jednostkowe w Javie</li>
<li>JAVA &#8211; Tworzenie aplikacji sieciowych za pomocą Springa, Hibernate i Eclipse</li>
<li>Eclipse Web Tools Platform &#8211; Tworzenie aplikacji WWW w języku Java</li>
<li>J2EE &#8211; Wzorce projektowe</li>
<li>Enterprise Java Beans 3.0 <em>(którą dostałem nieco wcześniej, ale jest mi szczególnie bliska ze względu na ostatnie tą platformą zainteresowanie)</em></li>
</ul>
<p>Z takim arsenałem lektur mam teraz zajęć na zimowe wieczory pod dostatkiem.  W tej jednak chwili prawdziwym dylematem będzie dla mnie pytanie &#8222;Od czego zacząć?&#8221; gdy zasiądę na kanapie z filiżanką kawy ;)</p>
<p>Muszę się zwierzyć, że książki papierowe to mój ulubiony sposób zdobywania wiedzy w zakresie programowania, ale też niestety najbardziej zaniedbany. W epoce Google&#8217;a trudno jest &#8216;marnować&#8217; czas na wyszukiwanie odpowiednich pozycji książkowych, podczas gdy łatwo sobie coś znaleźć w Sieci &#8216;na szybko&#8217;. Ja także stałem się ofiarą czegoś w rodzaju <em>fast-foodu</em> w dziedzinie zdobywania wiedzy (szybkie wyszukiwanie, krótka lektura <a href="http://wikipedia.org">wiki</a>, krótka lektura tutoriala, krótkie <a href="http://pl.wikipedia.org/wiki/Hello_world">&#8216;Hello World&#8217;</a> i już &#8216;znam&#8217; techonlogię) i trochę tego żałuję. Mam teraz idealną okazję, by nadrobić zaległości, pozagłębiać się trochę w szczegóły i &#8211; wreszcie &#8211; poznać polskie nazwy niektórych terminów, które stosuję w praktyce od dłuższego czasu (kolejna wada &#8216;fast-foodów wiedzy&#8217; to taka, że większość pozyskiwanych informacji przychodzi w języku angielskim i nie zna się jej oficjalnych tłumaczeń).</p>
<p>Dodatkową niespodzianką, jaka zawitała pod Świąteczne drzewko, była koszulka z bardzo fajnie wykonanym napisikiem (za którą dziękuję Adze i Zbigowi) ;)</p>
<p><img class="size-full wp-image-167" title="Prezenty pod choinką" src="http://xis.schowek.net/wp-content/uploads/2008/12/pc2500381.jpg" alt="Prezenty pod choinką" width="480" height="634" /></p>
<p style="text-align: center;">Wesołych Świąt!</p>
]]></content:encoded>
			<wfw:commentRss>http://xis.schowek.net/2008/12/25/hojna-gwiazdka/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Java Server Faces i parametry GET</title>
		<link>http://xis.schowek.net/2008/11/08/java-server-faces-i-parametry-get/</link>
		<comments>http://xis.schowek.net/2008/11/08/java-server-faces-i-parametry-get/#comments</comments>
		<pubDate>Sat, 08 Nov 2008 16:22:09 +0000</pubDate>
		<dc:creator>xis</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[EJB]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[Java Server Faces]]></category>
		<category><![CDATA[JSF]]></category>

		<guid isPermaLink="false">http://xis.schowek.net/?p=50</guid>
		<description><![CDATA[Java Server Faces to całkiem ciekawy framework dla Javy. O jego zaletach dużo by pisać, toteż odsyłam w tym temacie do odpowiednich wpisów w Sieci. JSF ma jednak jedną wadę; dość słabo wspiera przesyłanie parametrów za pomocą metody GET protokołu HTTP. Oto krótki poradnik jak używać parametrów przekazanych za pomocą metody GET do strony obsługiwanej [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://java.sun.com/javaee/javaserverfaces/">Java Server Faces</a> to całkiem ciekawy framework dla Javy. O jego zaletach dużo by pisać, toteż odsyłam w tym temacie do odpowiednich wpisów w Sieci. JSF ma jednak jedną wadę; dość słabo wspiera przesyłanie parametrów za pomocą metody <a href="http://en.wikipedia.org/wiki/HTTP">GET protokołu HTTP</a>. Oto krótki poradnik jak używać parametrów przekazanych za pomocą metody GET do strony obsługiwanej przez Java Server Faces.</p>
<p>Załóżmy, że mamy listę pracowników, z poziomu której możemy podejrzeć konkretnego zatrudnionego. Do obsługi naszej miniaplikacji wykorzystamy zatem dwie  strony <code>employee_list.jsp</code> i <code>employee.jsp</code>. Przyjmijmy także, że chcielibyśmy, aby dostęp do szczegółów dot. pracownika możliwy był po wprowadzeniu adresu np. <a href="http://localhost:8080/company/employee.jsf?e=10">http://localhost:8080/company/employee.jsf?e=10</a>.  Naszą aplikację zasili ziarno zarządzane (<em>managed bean</em>) <code>CompanyController</code>, którą wyposażamy we własność <code>selectedEmployeeId</code> i własność <code>selectedEmployee</code> zawierającą obiekt wskazanego pracownika:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">net.schowek.jsf.ui</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> CompanyController
<span style="color: #009900;">&#123;</span>
    @EJB
    CompanyServiceLocal companyService<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> DataModel   empDataModel<span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Long</span>        selectedEmployeeId<span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">private</span> Employee    selectedEmployee<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> DataModel getAllEmployees<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        empDataModel <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> ListDataModel<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        empDataModel.<span style="color: #006633;">setWrappedData</span><span style="color: #009900;">&#40;</span> companyService.<span style="color: #006633;">findAll</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">return</span> empDataModel<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> Employee getSelectedEmployee<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>selectedEmployee <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            selectedEmployee <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>Employee<span style="color: #009900;">&#41;</span> companyService.<span style="color: #006633;">findById</span><span style="color: #009900;">&#40;</span> selectedEmployeeId <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000000; font-weight: bold;">return</span> selectedEmployee<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setSelectedEmployee<span style="color: #009900;">&#40;</span> Employee selectedEmployee <span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">selectedEmployee</span> <span style="color: #339933;">=</span> selectedEmployee<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Long</span> getSelectedEmployeeId<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> selectedEmployeeId<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setSelectedEmployeeId<span style="color: #009900;">&#40;</span> <span style="color: #003399;">Long</span> selectedEmployeeId <span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">selectedEmployeeId</span> <span style="color: #339933;">=</span> selectedEmployeeId<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Wygląda to więc dość standardowo, tylko posługujemy sie tą tajemniczą własnością <code>selectedEmployeeId</code>. I skąd nasz <code>CompanyController</code> ma wiedzieć, że w tejże własności ma znaleźć się parametr przekazany w metodzie GET pod zmienną &#8216;<code>e</code>&#8216;?</p>
<p>Zdefiniujemy to pliku <code>faces-config.xml</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #ddbb00;">&amp;lt;</span>managed-bean<span style="color: #ddbb00;">&amp;gt;</span>
    <span style="color: #ddbb00;">&amp;lt;</span>managed-bean-name<span style="color: #ddbb00;">&amp;gt;</span>company<span style="color: #ddbb00;">&amp;lt;</span>/managed-bean-name<span style="color: #ddbb00;">&amp;gt;</span>
    <span style="color: #ddbb00;">&amp;lt;</span>managed-bean-class<span style="color: #ddbb00;">&amp;gt;</span>net.schowek.jsf.ui.CompanyController<span style="color: #ddbb00;">&amp;lt;</span>/managed-bean-class<span style="color: #ddbb00;">&amp;gt;</span>
    <span style="color: #ddbb00;">&amp;lt;</span>managed-bean-scope<span style="color: #ddbb00;">&amp;gt;</span>request<span style="color: #ddbb00;">&amp;lt;</span>/managed-bean-scope<span style="color: #ddbb00;">&amp;gt;</span>
    <span style="color: #ddbb00;">&amp;lt;</span>managed-property<span style="color: #ddbb00;">&amp;gt;</span>
        <span style="color: #ddbb00;">&amp;lt;</span>property-name<span style="color: #ddbb00;">&amp;gt;</span>selectedEmployeeId<span style="color: #ddbb00;">&amp;lt;</span>/property-name<span style="color: #ddbb00;">&amp;gt;</span>
        <span style="color: #ddbb00;">&amp;lt;</span>value<span style="color: #ddbb00;">&amp;gt;</span>#{param.e}<span style="color: #ddbb00;">&amp;lt;</span>/value<span style="color: #ddbb00;">&amp;gt;</span>
    <span style="color: #ddbb00;">&amp;lt;</span>/managed-property<span style="color: #ddbb00;">&amp;gt;</span>
<span style="color: #ddbb00;">&amp;lt;</span>/managed-bean<span style="color: #ddbb00;">&amp;gt;</span></pre></div></div>

<p>Oraz nasze pliczki stron:</p>
<p>Lista pracowników:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #ddbb00;">&amp;lt;</span>!-- employee_list.jsp --<span style="color: #ddbb00;">&amp;gt;</span>
<span style="color: #ddbb00;">&amp;lt;</span>f:view<span style="color: #ddbb00;">&amp;gt;</span>
    <span style="color: #ddbb00;">&amp;lt;</span>h:form<span style="color: #ddbb00;">&amp;gt;</span>
        <span style="color: #ddbb00;">&amp;lt;</span>h:datatable var=&quot;employee&quot; value=&quot;#{company.allEmployees}&quot;<span style="color: #ddbb00;">&amp;gt;</span>
            <span style="color: #ddbb00;">&amp;lt;</span>h:column<span style="color: #ddbb00;">&amp;gt;</span>
                <span style="color: #ddbb00;">&amp;lt;</span>h:outputtext value=&quot;#{employee.id}&quot; /<span style="color: #ddbb00;">&amp;gt;</span>
            <span style="color: #ddbb00;">&amp;lt;</span>/h:column<span style="color: #ddbb00;">&amp;gt;</span>
            <span style="color: #ddbb00;">&amp;lt;</span>h:column<span style="color: #ddbb00;">&amp;gt;</span>
                <span style="color: #ddbb00;">&amp;lt;</span>h:outputtext value=&quot;#{employee.name}&quot; /<span style="color: #ddbb00;">&amp;gt;</span>
            <span style="color: #ddbb00;">&amp;lt;</span>/h:column<span style="color: #ddbb00;">&amp;gt;</span>
            <span style="color: #ddbb00;">&amp;lt;</span>h:column<span style="color: #ddbb00;">&amp;gt;</span>
                <span style="color: #ddbb00;">&amp;lt;</span>h:outputlink value=&quot;employee.jsf&quot;<span style="color: #ddbb00;">&amp;gt;</span>
                    <span style="color: #ddbb00;">&amp;lt;</span>f:verbatim<span style="color: #ddbb00;">&amp;gt;</span>Szczegóły<span style="color: #ddbb00;">&amp;lt;</span>/f:verbatim<span style="color: #ddbb00;">&amp;gt;</span>
                    <span style="color: #ddbb00;">&amp;lt;</span>f:param value=&quot;#{employee.id}&quot; name=&quot;e&quot; /<span style="color: #ddbb00;">&amp;gt;</span>
                <span style="color: #ddbb00;">&amp;lt;</span>/h:outputlink<span style="color: #ddbb00;">&amp;gt;</span>
            <span style="color: #ddbb00;">&amp;lt;</span>/h:column<span style="color: #ddbb00;">&amp;gt;</span>
        <span style="color: #ddbb00;">&amp;lt;</span>/h:datatable<span style="color: #ddbb00;">&amp;gt;</span>
    <span style="color: #ddbb00;">&amp;lt;</span>/h:form<span style="color: #ddbb00;">&amp;gt;</span>
<span style="color: #ddbb00;">&amp;lt;</span>/f:view<span style="color: #ddbb00;">&amp;gt;</span></pre></div></div>

<p>&#8230;, karta pracownika&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #ddbb00;">&amp;lt;</span>!-- employee.jsp --<span style="color: #ddbb00;">&amp;gt;</span>
<span style="color: #ddbb00;">&amp;lt;</span>f:view<span style="color: #ddbb00;">&amp;gt;</span>
    <span style="color: #ddbb00;">&amp;lt;</span>h:form<span style="color: #ddbb00;">&amp;gt;</span>
        <span style="color: #ddbb00;">&amp;lt;</span>h2<span style="color: #ddbb00;">&amp;gt;</span>Szczegóły pracownika #<span style="color: #ddbb00;">&amp;lt;</span>h:outputText value=&quot;#company.selectedEmployee.id&quot;/<span style="color: #ddbb00;">&amp;gt;&amp;lt;</span>/h2<span style="color: #ddbb00;">&amp;gt;</span>
        <span style="color: #ddbb00;">&amp;lt;</span>div<span style="color: #ddbb00;">&amp;gt;</span>
            <span style="color: #ddbb00;">&amp;lt;</span>span<span style="color: #ddbb00;">&amp;gt;</span>Imię i nazwisko:<span style="color: #ddbb00;">&amp;lt;</span>/span<span style="color: #ddbb00;">&amp;gt;</span>
            <span style="color: #ddbb00;">&amp;lt;</span>span<span style="color: #ddbb00;">&amp;gt;&amp;lt;</span>h:outputText value=&quot;#company.selectedEmployee.name&quot;/<span style="color: #ddbb00;">&amp;gt;&amp;lt;</span>/span<span style="color: #ddbb00;">&amp;gt;</span>
        <span style="color: #ddbb00;">&amp;lt;</span>/div<span style="color: #ddbb00;">&amp;gt;</span>
        <span style="color: #ddbb00;">&amp;lt;</span>div<span style="color: #ddbb00;">&amp;gt;</span>
            <span style="color: #ddbb00;">&amp;lt;</span>span<span style="color: #ddbb00;">&amp;gt;</span>Stanowisko:<span style="color: #ddbb00;">&amp;lt;</span>/span<span style="color: #ddbb00;">&amp;gt;</span>
            <span style="color: #ddbb00;">&amp;lt;</span>span<span style="color: #ddbb00;">&amp;gt;&amp;lt;</span>h:outputText value=&quot;#company.selectedEmployee.position&quot;/<span style="color: #ddbb00;">&amp;gt;&amp;lt;</span>/span<span style="color: #ddbb00;">&amp;gt;</span>
        <span style="color: #ddbb00;">&amp;lt;</span>/div<span style="color: #ddbb00;">&amp;gt;</span>
        <span style="color: #ddbb00;">&amp;lt;</span>div<span style="color: #ddbb00;">&amp;gt;</span>
            <span style="color: #ddbb00;">&amp;lt;</span>span<span style="color: #ddbb00;">&amp;gt;</span>Dodatkowe informacje:<span style="color: #ddbb00;">&amp;lt;</span>/span<span style="color: #ddbb00;">&amp;gt;</span>
            <span style="color: #ddbb00;">&amp;lt;</span>div<span style="color: #ddbb00;">&amp;gt;&amp;lt;</span>h:outputText value=&quot;#company.selectedEmployee.comments&quot;/<span style="color: #ddbb00;">&amp;gt;&amp;lt;</span>/div<span style="color: #ddbb00;">&amp;gt;</span>
        <span style="color: #ddbb00;">&amp;lt;</span>/div<span style="color: #ddbb00;">&amp;gt;</span>
    <span style="color: #ddbb00;">&amp;lt;</span>/h:form<span style="color: #ddbb00;">&amp;gt;</span>
<span style="color: #ddbb00;">&amp;lt;</span>/f:view<span style="color: #ddbb00;">&amp;gt;</span></pre></div></div>

<p>Takie rozwiązanie ma jednak dość poważną wadę, bowiem wspiera jedynie ziarna zarządzane, których zasięg (<em>scope</em>) dotyczy żądania. Własności ziaren zarządzanych deklarowanych w pliku <code>faces-config.xml</code> muszą mieć czas życia co najmniej taki jak czas życia samego ziarna, toteż <code>#{param}</code>, który żyje tylko wraz z żądaniem ogranicza zasięg całego ziarna. Często jednak zdarza się, że potrzebujemy ziarna żyjącego przez całą sesję, wtedy nie możemy skorzystać z własności deklarowanej w <code>faces-config.xml</code>. Możemy jednak, zamiast oczekiwać wstrzyknięcia wartości naszej własności przez JSF, sami pobrać wartość parametru żądania.</p>
<p>W tym celu usuwamy z pliku <code>faces-config.xml</code> deklarację parametru pozostawiając:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #ddbb00;">&amp;lt;</span>managed-bean<span style="color: #ddbb00;">&amp;gt;</span>
    <span style="color: #ddbb00;">&amp;lt;</span>managed-bean-name<span style="color: #ddbb00;">&amp;gt;</span>company<span style="color: #ddbb00;">&amp;lt;</span>/managed-bean-name<span style="color: #ddbb00;">&amp;gt;</span>
    <span style="color: #ddbb00;">&amp;lt;</span>managed-bean-class<span style="color: #ddbb00;">&amp;gt;</span>net.schowek.jsf.ui.CompanyController<span style="color: #ddbb00;">&amp;lt;</span>/managed-bean-class<span style="color: #ddbb00;">&amp;gt;</span>
    <span style="color: #ddbb00;">&amp;lt;</span>managed-bean-scope<span style="color: #ddbb00;">&amp;gt;</span>request<span style="color: #ddbb00;">&amp;lt;</span>/managed-bean-scope<span style="color: #ddbb00;">&amp;gt;</span>
<span style="color: #ddbb00;">&amp;lt;</span>/managed-bean<span style="color: #ddbb00;">&amp;gt;</span></pre></div></div>

<p>Modyfikujemy tez nasze ziarno usuwając własność <code>selectedEmployeeId</code> wraz z <em>getterem</em> i <em>setterem</em> i zmieniając metodę <code>getSelectedEmployee()</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> Employee getSelectedEmployee<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  Map<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>String, String<span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> reqParams <span style="color: #339933;">=</span> FacesContext.<span style="color: #006633;">getCurrentInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getExternalContext</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getRequestParameterMap</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #003399;">String</span> eId <span style="color: #339933;">=</span> reqParams.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;e&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #003399;">Long</span> selectedEmployeeId <span style="color: #339933;">=</span> <span style="color: #003399;">Long</span>.<span style="color: #006633;">parseLong</span><span style="color: #009900;">&#40;</span> eId <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>selectedEmployee <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    selectedEmployee <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>Employee<span style="color: #009900;">&#41;</span> companyService.<span style="color: #006633;">findById</span><span style="color: #009900;">&#40;</span> selectedEmployeeId <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000000; font-weight: bold;">return</span> selectedEmployee<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Od tej pory ziarno o czasie życia sesji również potrafi obsługiwać parametry GET, a my możemy dodawać do zakładek odnośniki do kart konkretnych pracowników :)</p>
]]></content:encoded>
			<wfw:commentRss>http://xis.schowek.net/2008/11/08/java-server-faces-i-parametry-get/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Bałagan w mrowisku</title>
		<link>http://xis.schowek.net/2008/11/04/balagan-w-mrowisku/</link>
		<comments>http://xis.schowek.net/2008/11/04/balagan-w-mrowisku/#comments</comments>
		<pubDate>Tue, 04 Nov 2008 08:54:24 +0000</pubDate>
		<dc:creator>xis</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[Ant]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://xis.schowek.net/2008/11/04/balagan-w-mrowisku/</guid>
		<description><![CDATA[Dość długo nic nie pisałem, szczerze mówiąc zastanawiałem się, czy nie przestać całkowicie (jak się okazuje, strasznie trudno pisać o tym, co możnaby w tym czasie robić ;) ), ale postanowiłem coś jednak naskrobać i dalej prowadzić ten swój zapiśnik. Nie będę chyba jednak publikował wpisów zbyt często, bo postanowiłem już całkowicie sprowadzić tego bloga [...]]]></description>
			<content:encoded><![CDATA[<p>Dość długo nic nie pisałem, szczerze mówiąc zastanawiałem się, czy nie przestać całkowicie (jak się okazuje, strasznie trudno pisać o tym, co możnaby w tym czasie robić ;) ), ale postanowiłem coś jednak naskrobać i dalej prowadzić ten swój zapiśnik. Nie będę chyba jednak publikował wpisów zbyt często, bo postanowiłem już całkowicie sprowadzić tego bloga do roli swego rodzaju notatnika zawierającego po prostu rzeczy do zapamiętania.</p>
<p>Dziś o pewnym narzędziu, z którym życie programisty <a href="http://pl.wikipedia.org/wiki/Java">Java</a> staje się łatwiejsze &#8211; <a href="http://ant.apache.org/">Ant</a>.</p>
<p>Ant to &#8211; jak pewnie każdy <em>Javowiec</em> wie &#8211; doskonałe narzędzie upraszczające nie tylko proces budowania projektów, ale pomagające zautomatyzować każdą rutynową operację. Wachlarz instrukcji, które potrafi on wykonać jest ogromny i stale się powiększa.</p>
<p>Ostatnio miałem okazję budować projekt, który zależał od kilku innych podprojektów, których z kolei wynikami były różne typy archiwów (<a href="http://pl.wikipedia.org/wiki/JAR_(format_pliku)">JAR</a>/<a href="http://en.wikipedia.org/wiki/WAR_file">WAR</a>). Całość (projekt główny) była pakietem <a href="http://en.wikipedia.org/wiki/Web_module#Modules">EAR</a> zawierającym wspomniane wcześniej archiwa. Z poziomu mojego ulubionego <a href="http://www.eclipse.org/">Eclipse</a> można oczywiście wyklikać eksport owych składników do projektu docelowego, ale wykonywanie tego przy każdej próbie sprawdzenia efektów swojej pracy było dość uciążliwe. Na szczęście Eclipse jest doskonale zintegrowany z Antem, toteż przygotowanie pliku budującego dla moich projektów trwało dosłownie chwilę. Ant dysponuje również instrukcją &#8216;ant&#8217; pozwalającą na wykonanie innego pliku budującego z poziomu pliku głównego. To idealne rozwiązanie dla mojej sytuacji z podprojektami.</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #ddbb00;">&amp;lt;</span>property name=&quot;ejbjar.dir&quot; value=&quot;${basedir}/../MyEJBModule&quot;/<span style="color: #ddbb00;">&amp;gt;</span>
<span style="color: #ddbb00;">&amp;lt;</span>property name=&quot;webmodule.dir&quot; value=&quot;${basedir}/../MyWEBModule&quot;/<span style="color: #ddbb00;">&amp;gt;</span>        
<span style="color: #ddbb00;">&amp;lt;</span>target name=&quot;preparecomponents&quot;<span style="color: #ddbb00;">&amp;gt;</span>
  <span style="color: #ddbb00;">&amp;lt;</span>ant antfile=&quot;build.xml&quot; dir=&quot;${ejbjar.dir}&quot;/<span style="color: #ddbb00;">&amp;gt;</span>
  <span style="color: #ddbb00;">&amp;lt;</span>ant antfile=&quot;build.xml&quot; dir=&quot;${webmodule.dir}&quot;/<span style="color: #ddbb00;">&amp;gt;</span>
<span style="color: #ddbb00;">&amp;lt;</span>/target<span style="color: #ddbb00;">&amp;gt;</span></pre></div></div>

<p>Pojawił się jednak pewien problem, otóż tak wykonywane skrypty Ant&#8217;a posiadały dość dziwne własności (<em>properties</em>). Okazało się, że dziedziczą one po projekcie głównym i tak najczęściej używane przeze mnie własności jak np. <em>project.distname</em>, czy <em>basedir</em> miały wartości zdefiniowane w projekcie głównym, a nie te, których definicja występowała u nich samych, co oczywiście powodowało błędy przy budowaniu i ogólną porażkę. Rozwiązaniem może tu być zmiana nazw własności na unikalne dla każdego z projektów, ale to oczywiście nie jest najelegantsze rozwiązanie, pomijając już jego sensowność.</p>
<p>Na szczęście Ant zabezpiecza nas przed tym dodając atrybut <em>inheritall</em>, pozwalający na zbudowanie zupełnie nowego środowiska dla każdego poszczególnego skryptu wykonywanego z poziomu skryptu głównego.</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #ddbb00;">&amp;lt;</span>target name=&quot;preparecomponents&quot;<span style="color: #ddbb00;">&amp;gt;</span>
  <span style="color: #ddbb00;">&amp;lt;</span>ant antfile=&quot;build.xml&quot; dir=&quot;${ejbjar.dir}&quot; inheritall=&quot;false&quot;/<span style="color: #ddbb00;">&amp;gt;</span>
  <span style="color: #ddbb00;">&amp;lt;</span>ant antfile=&quot;build.xml&quot; dir=&quot;${webmodule.dir}&quot; inheritall=&quot;false&quot;/<span style="color: #ddbb00;">&amp;gt;</span>
<span style="color: #ddbb00;">&amp;lt;</span>/target<span style="color: #ddbb00;">&amp;gt;</span></pre></div></div>

<p>W ten sposób każdy z komponentów zostanie zbudowany tak, jakbyśmy wykonali osobno każdy ze skryptów budowania. Warto zanotować, że w elemencie <em>ant</em> można zagnieżdżać elementy <em>property</em> i przekazywać je do wykonywanego skryptu, zatem komunikacja skryptu głównego z komponentami jest również możliwa.</p>
]]></content:encoded>
			<wfw:commentRss>http://xis.schowek.net/2008/11/04/balagan-w-mrowisku/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WSDL2Java i własny generator kodu</title>
		<link>http://xis.schowek.net/2007/09/27/wsdl2java-i-wlasny-generator/</link>
		<comments>http://xis.schowek.net/2007/09/27/wsdl2java-i-wlasny-generator/#comments</comments>
		<pubDate>Thu, 27 Sep 2007 07:54:09 +0000</pubDate>
		<dc:creator>xis</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[Axis]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[WebServices]]></category>
		<category><![CDATA[WSDL2Java]]></category>

		<guid isPermaLink="false">http://xis.schowek.net/2007/09/27/wsdl2java-i-wlasny-generator/</guid>
		<description><![CDATA[Użytkownicy usług sieciowych w Javie często używają narzędzia WSDL2Java &#8211; nie ma chyba prostszego sposobu na &#8216;napisanie&#8217; klienta usługi niż ten. Wystarczy plik WSDL i jedna komenda, i ciach - mamy klienta. Co jednak, jeśli nasza usługa polega na wymianie obiektów naszych klas? Takie obiekty będą zwracane, albo przekazywane jako argument w metodach wykonanych przez usługę. [...]]]></description>
			<content:encoded><![CDATA[<p>Użytkownicy <a HREF="http://en.wikipedia.org/wiki/Web_service">usług sieciowych</a> w <a HREF="http://java.sun.com/">Javie</a> często używają narzędzia <a HREF="http://ws.apache.org/axis/java/user-guide.html#WSDL2JavaBuildingStubsSkeletonsAndDataTypesFromWSDL">WSDL2Java</a> &#8211; nie ma chyba prostszego sposobu na &#8216;napisanie&#8217; klienta usługi niż ten. Wystarczy plik <a HREF="http://www.w3.org/TR/wsdl">WSDL</a> i jedna komenda, i ciach - mamy klienta. Co jednak, jeśli nasza usługa polega na wymianie obiektów naszych klas? Takie obiekty będą zwracane, albo przekazywane jako argument w metodach wykonanych przez usługę. Oznacza to, że &#8211; zgodnie z WSDL &#8211; klient i serwer muszą mieć definicje tych klas. Niestety, w praktyce oznacza to też, że ta sama klasa będzie zdefiniowana dwa razy (dla klienta i dla serwera osobno). Problem zaczyna się wtedy, gdy chcemy naszą klasę wyposażyć w jakieś dodatkowe metody, które chcielibyśmy wykorzystać zarówno po stronie serwera, jak i klienta.</p>
<p>Przykładowa sytuacja:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">net.schowek.ws.server</span><span style="color: #339933;">;</span>             
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Foo 
<span style="color: #009900;">&#123;</span> 
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">int</span> bar<span style="color: #339933;">;</span>         
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">int</span> getBar<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> 
    <span style="color: #009900;">&#123;</span> 
        <span style="color: #000000; font-weight: bold;">return</span> bar<span style="color: #339933;">;</span> 
    <span style="color: #009900;">&#125;</span>           
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setBar<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> bar<span style="color: #009900;">&#41;</span> 
    <span style="color: #009900;">&#123;</span> 
         <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">bar</span> <span style="color: #339933;">=</span> bar<span style="color: #339933;">;</span> 
    <span style="color: #009900;">&#125;</span>              
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> blah<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> 
    <span style="color: #009900;">&#123;</span> 
        <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;BLAH: &quot;</span><span style="color: #339933;">+</span>bar<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
    <span style="color: #009900;">&#125;</span> 
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Niech nasza klasa serwisu wygląda tak:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">net.schowek.ws.server</span><span style="color: #339933;">;</span>        
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> FooService 
<span style="color: #009900;">&#123;</span> 
    <span style="color: #000000; font-weight: bold;">public</span> Foo getFoo<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> b<span style="color: #009900;">&#41;</span> 
    <span style="color: #009900;">&#123;</span> 
        Foo f <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Foo<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
        f.<span style="color: #006633;">setBar</span><span style="color: #009900;">&#40;</span>b<span style="color: #009900;">&#41;</span> 
        <span style="color: #000000; font-weight: bold;">return</span> f<span style="color: #339933;">;</span> 
    <span style="color: #009900;">&#125;</span> 
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Jeśli nasza usługa udostępni obiekt klasy <code>Foo</code>, to WSDL2Java wygeneruje kod w pakiecie np. <code>net.schowek.ws.client</code>, w którym zdefiniowana będzie klasa <code>Foo</code>, ale bez metody <code>blah()</code> (wygeneruje tylko <em>gettery</em> i <em>settery</em>).<br />
A szkoda, bo całą funcjonalność prawdopodobnie będziemy musieli klientowi implementować od nowa.<br />
Spróbujmy więc zaplanować inną architekturę. Niech nasza klasa <code>Foo</code> powędruje do pakietu <code>net.schowek.ws.common</code>, a pakiet serwera niech zaimplementuje jedynie <code>FooService</code>, zwracającą obiekt klasy <code>Foo</code> w pakiecie wspólnym. Byłoby super, gdyby <code>WSDL2Java</code> wygenerował nam teraz kod, który również dziedziczyłby po pakiecie <code>net.schowek.ws.common</code>.<br />
Jak tego dokonać? No właśnie.<br />
Twórcy <a HREF="http://ws.apache.org/axis/">Axis&#8217;a</a>, w którego skład wchodzi WSDL2Java pomyśleli o tym i pozwolili użytkownikowi na skonstruowanie własnych <em>generatorów kodu</em>. Wystarczy zaimplementować własną klasę WSDL2Java:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">net.schowek.ws.tools</span><span style="color: #339933;">;</span>        
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MyWSDL2Java <span style="color: #000000; font-weight: bold;">extends</span> WSDL2Java 
<span style="color: #009900;">&#123;</span> 
    <span style="color: #000000; font-weight: bold;">public</span> MyWSDL2Java<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>  <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span>            
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #003399;">Parser</span> createParser<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> 
    <span style="color: #009900;">&#123;</span> 
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> MyEmitter<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
    <span style="color: #009900;">&#125;</span>        
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> args<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> 
    <span style="color: #009900;">&#123;</span> 
        MyWSDL2Java w2j <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MyWSDL2Java<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
        w2j.<span style="color: #006633;">run</span><span style="color: #009900;">&#40;</span>args<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
    <span style="color: #009900;">&#125;</span> 
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Własną klasę emitera:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">net.schowek.ws.tools</span><span style="color: #339933;">;</span>        
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MyEmitter <span style="color: #000000; font-weight: bold;">extends</span> Emitter 
<span style="color: #009900;">&#123;</span> 
    <span style="color: #000000; font-weight: bold;">public</span> MyEmitter<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> 
    <span style="color: #009900;">&#123;</span> 
        MyGeneratorFactory factory <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MyGeneratorFactory<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
        setFactory<span style="color: #009900;">&#40;</span>factory<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
        factory.<span style="color: #006633;">setEmitter</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
    <span style="color: #009900;">&#125;</span> 
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Własną fabrykę generatorów:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">net.schowek.ws.tools</span><span style="color: #339933;">;</span>        
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MyGeneratorFactory <span style="color: #000000; font-weight: bold;">extends</span> JavaGeneratorFactory 
<span style="color: #009900;">&#123;</span> 
    <span style="color: #000000; font-weight: bold;">public</span> Generator getGenerator<span style="color: #009900;">&#40;</span>TypeEntry type, SymbolTable symbolTable<span style="color: #009900;">&#41;</span> 
    <span style="color: #009900;">&#123;</span> 
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>include<span style="color: #009900;">&#40;</span>type.<span style="color: #006633;">getQName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> 
        <span style="color: #009900;">&#123;</span> 
            <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> MyGeneratorWriter<span style="color: #009900;">&#40;</span>emitter, type, symbolTable<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
        <span style="color: #009900;">&#125;</span> 
        <span style="color: #000000; font-weight: bold;">else</span> 
        <span style="color: #009900;">&#123;</span> 
            <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> NoopGenerator<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
        <span style="color: #009900;">&#125;</span> 
    <span style="color: #009900;">&#125;</span> 
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>&#8230; i wreszcie &#8211; sam generator.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">net.schowek.ws.tools</span><span style="color: #339933;">;</span>   
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MyGeneratorWriter <span style="color: #000000; font-weight: bold;">extends</span> JavaTypeWriter 
<span style="color: #009900;">&#123;</span> 
    <span style="color: #000000; font-weight: bold;">public</span> MyGeneratorWriter<span style="color: #009900;">&#40;</span> Emitter e, TypeEntry t, SymbolTable s <span style="color: #009900;">&#41;</span> 
    <span style="color: #009900;">&#123;</span> 
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span> e, t, s <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
    <span style="color: #009900;">&#125;</span>   
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> JavaWriter getBeanWriter<span style="color: #009900;">&#40;</span> Emitter emitter, TypeEntry type, TypeEntry base <span style="color: #009900;">&#41;</span> 
    <span style="color: #009900;">&#123;</span> 
        <span style="color: #003399;">Vector</span> elements <span style="color: #339933;">=</span> type.<span style="color: #006633;">getContainedElements</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
        <span style="color: #003399;">Vector</span> attributes <span style="color: #339933;">=</span> type.<span style="color: #006633;">getContainedAttributes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
        <span style="color: #003399;">Boolean</span> isComplexFault <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Boolean</span><span style="color: #009900;">&#41;</span>type.<span style="color: #006633;">getDynamicVar</span><span style="color: #009900;">&#40;</span> 
                              JavaGeneratorFactory.<span style="color: #006633;">COMPLEX_TYPE_FAULT</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>   
&nbsp;
        <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span> isComplexFault <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span> isComplexFault.<span style="color: #006633;">booleanValue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> 
        <span style="color: #009900;">&#123;</span> 
            <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">getBeanWriter</span><span style="color: #009900;">&#40;</span> emitter, type, base <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
        <span style="color: #009900;">&#125;</span>   
&nbsp;
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> MyBeanWriter<span style="color: #009900;">&#40;</span> emitter, type, elements, base, attributes, 
            getBeanHelperWriter<span style="color: #009900;">&#40;</span> emitter, type, elements, base, attributes, <span style="color: #000066; font-weight: bold;">false</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
    <span style="color: #009900;">&#125;</span> 
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>i <em>writer</em>, czyli klasę odpowiedzialną za generowanie odpowiedniego kodu (w tym przypadku &#8211; klasy)</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">net.schowek.ws.tools</span><span style="color: #339933;">;</span>        
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MyBeanWriter <span style="color: #000000; font-weight: bold;">extends</span> JavaBeanWriter 
<span style="color: #009900;">&#123;</span> 
    <span style="color: #000000; font-weight: bold;">protected</span> MyBeanWriter<span style="color: #009900;">&#40;</span> Emitter e, TypeEntry t1, <span style="color: #003399;">Vector</span> v1, 
                            TypeEntry t2, <span style="color: #003399;">Vector</span> v2, JavaWriter w <span style="color: #009900;">&#41;</span> 
    <span style="color: #009900;">&#123;</span> 
        <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span> e, t1, v1, t2, v2, w <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">enableSimpleConstructors</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span> 
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">enableDefaultConstructor</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span> 
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">enableFullConstructor</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span> 
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">enableMemberFields</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span> 
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">enableGetters</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span> 
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">enableSetters</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span> 
    <span style="color: #009900;">&#125;</span>            
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #003399;">String</span> getImplementsText<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> 
    <span style="color: #009900;">&#123;</span> 
        <span style="color: #003399;">String</span> s <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot; extends net.schowek.ws.common.&quot;</span> 
                 <span style="color: #339933;">+</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">getClassName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot; &quot;</span> 
                 <span style="color: #339933;">+</span> <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">getImplementsText</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
        <span style="color: #000000; font-weight: bold;">return</span> s<span style="color: #339933;">;</span> 
    <span style="color: #009900;">&#125;</span>        
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> writeAccessMethods<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> 
    <span style="color: #009900;">&#123;</span> 
        pw.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;    public &quot;</span> 
                 <span style="color: #339933;">+</span> className 
                 <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;( net.schowek.ws.common.&quot;</span> 
                 <span style="color: #339933;">+</span> className 
                 <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot; old ) { &quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>        
&nbsp;
        <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> names.<span style="color: #006633;">size</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> i <span style="color: #339933;">+=</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span> 
        <span style="color: #009900;">&#123;</span> 
            <span style="color: #003399;">String</span> variable <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#41;</span> names.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>i <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
            <span style="color: #003399;">String</span> typeName <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#41;</span> names.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
            <span style="color: #003399;">String</span> var <span style="color: #339933;">=</span> Utils.<span style="color: #006633;">capitalizeFirstChar</span><span style="color: #009900;">&#40;</span>variable<span style="color: #009900;">&#41;</span> 
            <span style="color: #003399;">String</span> getter <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #339933;">;</span>        
&nbsp;
            <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> typeName.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;boolean&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> 
            <span style="color: #009900;">&#123;</span> 
                getter <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;old.is&quot;</span> <span style="color: #339933;">+</span> var <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;()&quot;</span><span style="color: #339933;">;</span> 
            <span style="color: #009900;">&#125;</span> 
            <span style="color: #000000; font-weight: bold;">else</span> 
            <span style="color: #009900;">&#123;</span> 
                getter <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;old.get&quot;</span> <span style="color: #339933;">+</span> var <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;()&quot;</span><span style="color: #339933;">;</span> 
            <span style="color: #009900;">&#125;</span>        
&nbsp;
            pw.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;           this.set&quot;</span> <span style="color: #339933;">+</span> var <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;( &quot;</span><span style="color: #339933;">+</span>getter<span style="color: #339933;">+</span><span style="color: #0000ff;">&quot; );&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>        
&nbsp;
            <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;=</span> names.<span style="color: #006633;">size</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span> 
            <span style="color: #009900;">&#123;</span> 
                <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span> 
            <span style="color: #009900;">&#125;</span> 
        <span style="color: #009900;">&#125;</span>        
&nbsp;
        pw.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;    }&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
        pw.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
        <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">writeAccessMethods</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
    <span style="color: #009900;">&#125;</span> 
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Jak widać w konstruktorze klasy <code>MyBeanWriter</code>, generatory są całkiem fajnie konfigurowalne, dzięki czemu nasz kod może wyglądać naprawdę różnie. Żeby &#8216;wstrzyknąć&#8217; do wygenerowanego kodu informację o dziedziczeniu z pakietu wspólnego użyłem przesłonięcia metody <code>getImplementsText()</code> (skorzystałem z tego, że informacje o dziedziczeniu jest umieszczanie w Javie zaraz przed deklaracją i implementowaniu interfejsu) &#8211; ta metoda wywoła się na pewno, bo WSDL2Java już tak ma ;)<br />
Ze względu na fakt, że nasza wygenerowana klasa będzie dziedziczyć po klasie z pakietu wspólnego, nie ma potrzeby deklarowania jej własności, dlatego wyłączam <code>enableMemberFields</code> (należy jednak pamiętać, że pierwowzór klasy <code>Foo</code> w pakiecie <code>common</code> musi mieć własności o dostępie <em>protected</em>, a nie <em>private</em>). Ponadto, skoro włączyłem już <code>enableDefaultConstructor</code>, to postanowiłem wykonać też metodę, która wygeneruje mi konstruktor kopiujący z obiektu klasy nadrzędnej. W ten sposób zapewniłem możliwość rzutowania moich klas klienta i serwera w obie strony (w końcu mają być takie same, prawda?). Kod można oczywiście poprawić tak, by nazwę pakietu wspólnego dało się podawać np. jako opcję przy uruchomieniu, ale najważniejsze, że robi to co chciałem i tak jest fajnie :)</p>
]]></content:encoded>
			<wfw:commentRss>http://xis.schowek.net/2007/09/27/wsdl2java-i-wlasny-generator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

