<?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>Splatch's devblog</title>
	<atom:link href="http://blog.dywicki.pl/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.dywicki.pl</link>
	<description>Pragmatyzm kontrolowany</description>
	<lastBuildDate>Thu, 01 Dec 2011 15:47:57 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
		<item>
		<title>Przeprowadzka</title>
		<link>http://blog.dywicki.pl/2011/06/10/przeprowadzka/</link>
		<comments>http://blog.dywicki.pl/2011/06/10/przeprowadzka/#comments</comments>
		<pubDate>Fri, 10 Jun 2011 14:30:55 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Wiadomości]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=247</guid>
		<description><![CDATA[Po dłuższym czasie braku aktywności na tym blogu &#8211; postanowiłem przenieść część z postów, które zostały na nim opublikowane do nowego blogu, który tyczy się kwestii java, middleware itd. pod adresem dywicki.pl. Być może zawitają tam inne języki :), kto wie może i PHP? Wszystkie pozostałe posty są i nadal będą dostępne. Przy okazji zwijania tego [...]]]></description>
				<content:encoded><![CDATA[<p>Po dłuższym czasie braku aktywności na tym blogu &#8211; postanowiłem przenieść część z postów, które zostały na nim opublikowane do nowego blogu, który tyczy się kwestii java, middleware itd. pod adresem <a href="http://dywicki.pl">dywicki.pl</a>. Być może zawitają tam inne języki :), kto wie może i <acronym title="Pre-Hypertext Processing">PHP</acronym>? Wszystkie pozostałe posty są i nadal będą dostępne. Przy okazji zwijania tego bloga raz jeszcze chciałbym podziękować wszystkim tym, którzy dorzucili się do odzyskania zrzutu bazy danych z OVH w <a href="http://blog.dywicki.pl/2006/11/22/powrot/">2006 roku</a>.</p>
<p>Dla osób, które jeszcze subskrybują kanały <acronym title="Really Simple Syndication">RSS</acronym> z tego bloga &#8211; proszę o przepięcie na nowy adres &#8211; dywicki.pl, na pewno nie pożałujecie. Nowy blog z pewnością będzie aktualizowany częściej niż ten. :)</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2011/06/10/przeprowadzka/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Parę słów o tym co się dzieje</title>
		<link>http://blog.dywicki.pl/2009/06/05/pare-slow-o-tym-co-sie-dzieje/</link>
		<comments>http://blog.dywicki.pl/2009/06/05/pare-slow-o-tym-co-sie-dzieje/#comments</comments>
		<pubDate>Fri, 05 Jun 2009 06:00:05 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Wiadomości]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=244</guid>
		<description><![CDATA[Bardzo dużo czasu minęło od ostatniej noty, tym czasem ja w dalszym ciągu nie mam kiedy publikować not technicznych a tym bardziej &#8220;prywatnych&#8221;. Wynika to między innymi z tego, że rozpocząłem działalność gospodarczą. Moja firma nazywa się Code-House i zajmuje się doradztwem, szkoleniami jak i wytwarzaniem oprogramowania. Szczegóły oferty znajdziecie na stronie firmowej jeśli zostanie [...]]]></description>
				<content:encoded><![CDATA[<p>Bardzo dużo czasu minęło od ostatniej noty, tym czasem ja w dalszym ciągu nie mam kiedy publikować not technicznych a tym bardziej &#8220;prywatnych&#8221;. Wynika to między innymi z tego, że rozpocząłem działalność gospodarczą. Moja firma nazywa się <a href="http://code-house.org/">Code-House</a> i zajmuje się doradztwem, szkoleniami jak i wytwarzaniem oprogramowania. Szczegóły oferty znajdziecie na stronie firmowej jeśli zostanie w końcu uruchomiona. ;) No a tak na co dzień jestem pracownikiem kontraktowym.<br />
<span id="more-244"></span><br />
W <a href="http://blog.dywicki.pl/2008/12/09/timeunit-enum-in-java-and-class-inphp/#comment-39687">jednym</a> z komentarzy <a href="http://racjonalny.blogspot.com/">Tomasz Bartczak</a> zapytał o nowiny z życia takiej firmy. Tych którzy są zainteresowani tym tematem zapraszam na <a href="http://blog.code-house.org/">oficjalny blog</a> mojej firmy. Jako że jest on oficjalny raczej nie znajdziecie na nim przemyśleń o naturze polityków, ale z pewnością od czasu do czasu będę tam publikował noty techniczne oprócz nowin z firmy. Jeśli ktoś będzie zainteresowany wyłącznie technologią proszę subskrybować kanały odpowiednie dla danych kategorii. :-)</p>
<p>Ważnym pytaniem jest &#8211; co się stanie z tym blogiem? W sieci istnieje cała masa notatników która nie była aktualizowana od wieków, wszystko wskazuje na to że ten stanie się kolejnym. Może od czasu do czasu coś tu się pojawi ale ani tego nie obiecuję (jak zwykłem do tej pory robić) ani nie planuję.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2009/06/05/pare-slow-o-tym-co-sie-dzieje/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Java Servlet API 3.0</title>
		<link>http://blog.dywicki.pl/2008/12/22/java-servlet-api-3/</link>
		<comments>http://blog.dywicki.pl/2008/12/22/java-servlet-api-3/#comments</comments>
		<pubDate>Mon, 22 Dec 2008 10:35:47 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[tlumaczenia]]></category>
		<category><![CDATA[Wiadomości]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=243</guid>
		<description><![CDATA[Dnia wczorajszego na InfoQ o tym, że został udostępniony szkic specyfikacji Servlet API 3.0. Największe nowości to&#8230; adnotacje, które będą mogły być użyte w miejsce interfejsów i dziedziczenia. Łatwiejsze tworzenie, ang. Ease of Development (Eod): W wcześniejszym szkicu zostały zaprezentowane adnotacje jako sposób na stworzenie Servletu &#8211; POJO. Jakkolwiek po dyskusji i odpowiedzi społeczności adnotacje [...]]]></description>
				<content:encoded><![CDATA[<p>Dnia wczorajszego na <a href="http://infoq.com">InfoQ</a> o tym, że został udostępniony <a href="http://www.infoq.com/news/2008/12/servlet3_debate">szkic specyfikacji</a> Servlet <acronym title="Application Programming Interface">API</acronym> 3.0. Największe nowości to&#8230; adnotacje, które będą mogły być użyte w miejsce interfejsów i dziedziczenia.<br />
<span id="more-243"></span></p>
<blockquote>
<ul>
<li>Łatwiejsze tworzenie, ang. <em>Ease of Development</em> (Eod): W wcześniejszym szkicu zostały zaprezentowane adnotacje jako sposób na stworzenie Servletu &#8211; POJO. Jakkolwiek po dyskusji i odpowiedzi społeczności adnotacje @GET i @POST na poziomie metod zostały wycofane. Zostają jednak adnotacje dla typów &#8211; deklaracja sevletu @WebServlet oraz deklaracja filtru @ServletFilter, @WebServletContextListener będzie alternatywnym sposobem na zdefiniowanie context listenera. Dodatkowo adnotacje takie jak @Resouorce będą wspierane w aplikacjach webowych będą zachowywać się tak jak w starszej wersji specyfikacji (2.5).</li>
<li>Rozszerzalność: szkielety webowe zbudowane na bazie servletów są bardzo popularne. Jest ich bardzo wiele, do wyboru w zależności od problemów, które mają rozwiązywać. Specyfikacja będzie umożliwiała łatwiejszą konfigurację tychże szkieletów.</li>
<li>Przetwarzanie asynchroniczne: największym wyzwaniem i zmianą jaką podjęli autorzy specyfikacji. W poprzedniej wersji zostały zdefiniowane operacje zatrzymania (suspend) oraz wznowienia (resume). Po publikacji grupa ekspertów podjęła dyskusję na temat przypadków użycia takiego rozwiązania.</li>
</ul>
</blockquote>
<p>Na łamach <a href="http://www.infoq.com/news/2008/12/servlet3_debate">InfoQ</a> są fragmenty dyskusji na temat fragmentów specyfikacji. Ludzie z JBossa krytykują Jetty, inni krytykują grupę która pracuje nad specyfikacją, że kiepsko współpracuje ze społecznością.</p>
<p>Mam osobiście nadzieję, że ta burza mózgów wyjdzie nam na dobre i adnotacje w Servlet <acronym title="Application Programming Interface">API</acronym> 3.0 nie będą jedyną nowością. :-)</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2008/12/22/java-servlet-api-3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Typ wyliczeniowy TimeUnit w Javie oraz klasa w PHP</title>
		<link>http://blog.dywicki.pl/2008/12/09/timeunit-enum-in-java-and-class-inphp/</link>
		<comments>http://blog.dywicki.pl/2008/12/09/timeunit-enum-in-java-and-class-inphp/#comments</comments>
		<pubDate>Tue, 09 Dec 2008 16:10:00 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=242</guid>
		<description><![CDATA[Java od wersji 5.0 zawiera możliwość definiowania typów wyliczeniowych. Jednym z praktycznych przykładów zastosowania tego mechanizmu jest TimeUnit. Enum ten służy do konwertowania jednostek czasu pomiędzy różnymi wielkościami &#8211; na przykład z minut na sekundy. import java.util.concurrent.TimeUnit; // ... TimeUnit.MINUTES.toSeconds(55); Fajna sprawa &#8211; jeśli mamy do czynienia z konwersjami. Inny pożyteczny przykład to przekazywanie czasu [...]]]></description>
				<content:encoded><![CDATA[<p>Java od wersji 5.0 zawiera możliwość definiowania typów wyliczeniowych. Jednym z praktycznych przykładów zastosowania tego mechanizmu jest <a href="http://www.docjar.com/docs/api/java/util/concurrent/TimeUnit.html">TimeUnit</a>. Enum ten służy do konwertowania jednostek czasu pomiędzy różnymi wielkościami &#8211; na przykład z minut na sekundy.<br />
<span id="more-242"></span></p>
<pre class="brush: java;">
import java.util.concurrent.TimeUnit;
// ...
TimeUnit.MINUTES.toSeconds(55);
</pre>
<p>Fajna sprawa &#8211; jeśli mamy do czynienia z konwersjami. Inny pożyteczny przykład to przekazywanie czasu jako argumentu:</p>
<pre class="brush: java;">
package org.code_house.concurrent;

import java.util.Date;
import java.util.concurrent.TimeUnit;


public class Lock {
    void lock(TimeUnit unit, long value) throws InterruptedException {
        Thread.sleep(unit.toMillis(value));
    }

    public static void main(String[] args) throws Exception {
        System.out.println(&quot;before &quot; + new Date());

        new Lock().lock(TimeUnit.SECONDS, 30);

        System.out.println(&quot;after &quot; + new Date());
    }

}
</pre>
<p>Programista, który używa takiej klasy nie musi się więc przejmować konwertowaniem jednostek na milisekundy, które są podstawą do wywołania metody Thread.sleep.</p>
<p>TimeUnit obsługuje następujące wielkości:</p>
<ul>
<li>nanosekundy</li>
<li>mikrosekundy</li>
<li>milisekundy</li>
<li>sekundy</li>
<li>minuty</li>
<li>godziny</li>
<li>dni</li>
</ul>
<p>Posługując się kodem z Javy postanowiłem sobie przypomnieć nieco <acronym title="Pre-Hypertext Processing">PHP</acronym> i napisałem wersję tego typu wyliczeniowego dla PHP:</p>
<pre class="brush: php;">&lt;?php
// namespace org\code_house\util;
/**
 * A simple class for converting between time units.
 * 
 * @author Łukasz Dywicki &lt;luke@code-house.org&gt;
 */
class TimeUnit {

    /**
     * Nanoseconds.
     */
    const NANOS     = 0;

    /**
     * Microseconds.
     */
    const MICROS    = 1;

    /**
     * Milliseconds
     */
    const MILLIS    = 2;

    /**
     * Seconds.
     */
    const SECONDS   = 3;

    /**
     * Minutes.
     */
    const MINUTES   = 4;

    /**
     * Hours.
     */
    const HOURS     = 5;

    /**
     * Days.
     */
    const DAYS      = 6;

    /**
     * Conversion table between time units.
     * @var array
     */
    private static $modifiers = array(
         self::NANOS     =&gt; 0.000000001,
         self::MICROS    =&gt; 0.000001,
         self::MILLIS    =&gt; 0.001,
         self::SECONDS   =&gt; 1,
         self::MINUTES   =&gt; 60,
         self::HOURS     =&gt; 3600,
         self::DAYS      =&gt; 86400,
    );

    /**
     * Constructs new time unit.
     * 
     * @param $type TimeUnit Time unit base.
     */
    public function __construct($type) {
        if ($type &lt; TimeUnit::NANOS || $type &gt; TimeUnit::DAYS) {
            throw new RuntimeException('Time unit base is out of range');
        }
        $this-&gt;type = $type;
    }

    public function toNanos($value) {
        return TimeUnit::convert($this-&gt;type, $value, TimeUnit::NANOS);
    }

    public function toMicros($value) {
        return TimeUnit::convert($this-&gt;type, $value, TimeUnit::MICROS);
    }

    public function toMilis($value) {
        return TimeUnit::convert($this-&gt;type, $value, TimeUnit::MILLIS);
    }

    public function toSeconds($value) {
        return TimeUnit::convert($this-&gt;type, $value, TimeUnit::SECONDS);
    }

    public function toMinutes($value) {
        return TimeUnit::convert($this-&gt;type, $value, TimeUnit::MINUTES);
    }

    public function toHours($value) {
        return TimeUnit::convert($this-&gt;type, $value, TimeUnit::HOURS);
    }

    public function toDays($value) {
        return TimeUnit::convert($this-&gt;type, $value, TimeUnit::DAYS);
    }

    /**
     * Convert method.
     * 
     * @param $from Time unit
     * @param $value Number of values.
     * @param $to Time unit
     * @return decimal
     */
    private final static function convert($from, $value, $to) {
        if ($from === $to) {
            return $value;
        }

        $value *= self::$modifiers[$from];
        return $value / self::$modifiers[$to];
    }
}

// przykład użycia
$unit = new TimeUnit(TimeUnit::SECONDS);
echo $unit-&gt;toMinutes(60) .&quot;\n&quot;;

$unit = new TimeUnit(TimeUnit::HOURS);
echo $unit-&gt;toMinutes(1) .&quot;\n&quot;;

?&gt;</pre>
<p>Niestety brak pól z modyfikatorami <b>public static final</b> w <acronym title="Pre-Hypertext Processing">PHP</acronym> uniemożliwił zastosowanie choćby czegoś podobnego do typu wyliczeniowego.. Kod klasy dla <acronym title="Pre-Hypertext Processing">PHP</acronym> jest wolnodostępny. :-)</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2008/12/09/timeunit-enum-in-java-and-class-inphp/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>EasyMock i IAnswer, recepta na zachowanie metod</title>
		<link>http://blog.dywicki.pl/2008/12/03/easymock-inaswer-as-method-behaviour-recipe/</link>
		<comments>http://blog.dywicki.pl/2008/12/03/easymock-inaswer-as-method-behaviour-recipe/#comments</comments>
		<pubDate>Wed, 03 Dec 2008 16:06:42 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Porady]]></category>
		<category><![CDATA[Testy jednostkowe]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=240</guid>
		<description><![CDATA[Złym zwyczajem jest modyfikowanie argumentów zamiast zwracania nowej wartości, jakkolwiek trafiają się sytuacje gdy testowany kod powinien weryfikować takie wywołania. W EasyMock mamy do dyspozycji w takim przypadku interfejs IAnswer. Jego użycie jest w miarę proste &#8211; dobieramy się do tablicy argumentów i robimy z nią co potrzeba. Oto przykład &#8211; interfejs Populator dodaje do [...]]]></description>
				<content:encoded><![CDATA[<p>Złym zwyczajem jest modyfikowanie argumentów zamiast zwracania nowej wartości, jakkolwiek trafiają się sytuacje gdy testowany kod powinien weryfikować takie wywołania. W EasyMock mamy do dyspozycji w takim przypadku interfejs IAnswer. Jego użycie jest w miarę proste &#8211; dobieramy się do tablicy argumentów i robimy z nią co potrzeba.<br />
<span id="more-240"></span><br />
Oto przykład &#8211; interfejs Populator dodaje do przekazanej tablicy określoną wartość w puste miejsca. Zwraca też ilość zmian, które zaprowadził. Całość jest oparta na bardzo prostym kodzie, zaledwie jedna pętla, jakkolwiek na potrzeby przykładu jest to wystarczające. Pragnę jednak nadmienić, że w podobny sposób można testować bardziej złożony kod, gdzie kolaborują ze sobą dwa obiekty &#8211; tj. Observator i Observable czy też Visitor i Visitable.</p>
<pre class="brush: java;">package org.code_house.test.mock;

interface Populator {
    int fill(String value, String[] arguments);
}
</pre>
<p>Implementacja interfejsu jest bardzo prosta:</p>
<pre class="brush: java;">package org.code_house.test.mock;

class FillAnswer implements IAnswer&lt;Integer&gt; {
    public Integer answer() throws Throwable {
        // pobranie argumentow
        Object[] arguments = EasyMock.getCurrentArguments();
        String name = (String) arguments[0];
        Object[] values = (Object[]) arguments[1];

        // logika potrzebna do testu
        int populated = 0;
        for (int i = 0; i &lt; values.length; i++) {
            if (values[i] == null) {
                populated++;
                values[i] = name;
            }
        }
        return populated;
    }
}
</pre>
<p>Test jest również niezbyt skomplikowany &#8211; bazuje on na poprzedniej nocie &#8211; &#8220;Testowanie tablic argumentów z EasyMock&#8221;:</p>
<pre class="brush: java;">package org.code_house.test.mock;

import static org.easymock.EasyMock.*;
import org.easymock.IAnswer;

import java.util.Arrays;

import junit.framework.TestCase;

public class AnswerTest extends TestCase {

    public void testPopulate() {
        Populator populator = createMock(Populator.class);
        expect(populator.fill(eq(&quot;Code House&quot;), aryEq(new String[3])))
            .andAnswer(new FillAnswer());
        expect(populator.fill(eq(&quot;Code House&quot;), aryEq(new String[] {&quot;1&quot;})))
            .andAnswer(new FillAnswer());
        replay(populator);

        // tablica do wypełnienia
        String[] populated = new String[3];
        int added = populator.fill(&quot;Code House&quot;, populated);
        assertEquals(3, added);
        // w odpowiedzi oczekujemy dodania 3 nowych elementów
        assertTrue(Arrays.equals(
            new String[] {&quot;Code House&quot;, &quot;Code House&quot;, &quot;Code House&quot;},
            populated
        ));

        // w tym przypadku nie oczekujemy nowości
        added = populator.fill(&quot;Code House&quot;, new String[] {&quot;1&quot;});
        assertEquals(0, added);
    }
}
</pre>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2008/12/03/easymock-inaswer-as-method-behaviour-recipe/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Testowanie tablic argumentów z EasyMock</title>
		<link>http://blog.dywicki.pl/2008/11/26/testing-array-parameters-with-easymock/</link>
		<comments>http://blog.dywicki.pl/2008/11/26/testing-array-parameters-with-easymock/#comments</comments>
		<pubDate>Wed, 26 Nov 2008 06:00:02 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Porady]]></category>
		<category><![CDATA[Testy jednostkowe]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=239</guid>
		<description><![CDATA[Często zdarza się że metody, które piszemy i później testujemy mają argumenty w postaci tablic. EasyMock wówczas potrafi zgłosić wyjątek, że przekazana tablica jest różna od oczekiwanej mimo, że zawartość tablic jest identyczna. java.lang.AssertionError: Unexpected method call find([Ljava.lang.String;@1ad77a7): find([Ljava.lang.String;@b8f82d): expected: 1, actual: 0 package org.code_house.test.mock; import static org.easymock.EasyMock.aryEq; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.expect; import [...]]]></description>
				<content:encoded><![CDATA[<p>Często zdarza się że metody, które piszemy i później testujemy mają argumenty w postaci tablic. EasyMock wówczas potrafi zgłosić wyjątek, że przekazana tablica jest różna od oczekiwanej mimo, że zawartość tablic jest identyczna.<br />
<span id="more-239"></span></p>
<pre class="brush: java;">java.lang.AssertionError: 
  Unexpected method call find([Ljava.lang.String;@1ad77a7):
    find([Ljava.lang.String;@b8f82d): expected: 1, actual: 0
</pre>
<pre class="brush: java;">
package org.code_house.test.mock;

import static org.easymock.EasyMock.aryEq;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;

import java.util.Collections;
import java.util.List;

import junit.framework.TestCase;

interface Finder {
    List&lt;String&gt; find(String[] names);
}

public class FinderTest extends TestCase {

    public void testFind() {
        Finder mock = createMock(Finder.class);
        expect(mock.find(aryEq(new String[] {&quot;Amy&quot;, &quot;Luke&quot;}))).andReturn(
            Collections.EMPTY_LIST);
        replay(mock);

        List&lt;String&gt; list = mock.find(new String[] {&quot;Amy&quot;, &quot;Luke&quot;});
        assertTrue(list.isEmpty());
    }
}

</pre>
<p>Rozwiązaniem tych problemów jest użycie mechanizmu &#8220;matcherów&#8221;, które są wbudowane w sam szkielet. Najprostszym sposobem na ich użycie jest odwołanie przy pomocy statycznego wywołania którejś z metod EasyMock. Poniżej znajduje się lista dostępnych matcherów. Wartość &#8220;given&#8221; to argument przekazany w wywołaniu metody. </p>
<ul>
<li><strong>eq</strong>(X value)<br />
    Argument pasuje jeśli wyrażenie value.equals(given) zwróci true. Dostępny dla wszystkich typów prostych i obiektów.</li>
<li><strong>anyBoolean</strong>(), <strong>anyByte</strong>(), <strong>anyChar</strong>(), <strong>anyDouble</strong>(), <strong>anyFloat</strong>(), <strong>anyInt</strong>(), <strong>anyLong</strong>(), <strong>anyObject</strong>(), <strong>anyShort</strong>()<br />
    Dowolna wartość zostanie przepuszczona niezależnie od tego co będzie przekazane. Dostępny dla wszystkich typów.
</li>
<li><strong>eq</strong>(X value, X delta)<br />
    Pasuje jeśli aktualna jeśli wyrażenie given jest równe value z dokładnością do delta. Dostępne dla typów float oraz double.</li>
<li><strong>aryEq</strong>(X value)<br />
    Pasuje jeśli wyrażenie Arrays.equals(value, given) zwraca true. Dostępne dla tablic typów prostych jak i dla obiektów.</li>
<li><strong>isNull</strong>()<br />
    Pasuje jeśli given == null. Dostępne tylko dla obiektów.</li>
<li><strong>notNull</strong>()<br />
    Pasuje jeśli given != null. Dostępne tylko dla obiektów.</li>
<li><strong>same</strong>(X value)<br />
    Pasuje jeśli wyrażenie value == given jest prawdziwe. Dostępne tylko dla obiektów.</li>
<li><strong>isA</strong>(Class clazz)<br />
    Pasuje jeśli given instanceof clazz zwraca true. Given może być instancję clazz jak i pochodną.</li>
<li><strong>lt</strong>(X value), <strong>leq</strong>(X value), <strong>geq</strong>(X value), <strong>gt</strong>(X value)<br />
    Zwraca true jeśli given jest mniejsze, mniejsze równe, większe równe bądź większe niż value. Dostępne dla wszystkich numerycznych typów prostych.</li>
<li><strong>startsWith</strong>(String prefix), <strong>contains</strong>(String substring), <strong>endsWith</strong>(String suffix)<br />
    Zwraca true jeśli given  zaczyna się, zawiera bądź kończy się daną wartością. Dostępne dla argumentów typu String.</li>
<li><strong>matches</strong>(String regex), <strong>find</strong>(String regex)<br />
    Pasuje jeśli given pasuje w całości do wyrażenia/fragment pasuje. Dostępne dla argumentów typu String.</li>
<li><strong>and</strong>(X first, X second)<br />
    Zwraca true jeśli matcher first oraz second zwracają prawdę.</li>
<li><strong>or</strong>(X first, X second)<br />
    Zwraca true jeśli matcher first bądź second pasuje.</li>
<li><strong>not</strong>(X value)<br />
    Zwraca true jeśli matcher value zwrócił fałsz.</li>
</ul>
<p>Uzbrojeni w taki zestaw matcherów możemy poprawić kod testu tak by był on poprawny:</p>
<pre class="brush: java;">

public class FinderTest extends TestCase {

    public void testFind() {
        Finder mock = createMock(Finder.class);
        expect(mock.find(aryEq(new String[] {&quot;Amy&quot;, &quot;Luke&quot;}))).andReturn(
            Collections.EMPTY_LIST);
        replay(mock);

        List&lt;String&gt; list = mock.find(new String[] {&quot;Amy&quot;, &quot;Luke&quot;});
        assertTrue(list.isEmpty());
    }
}
</pre>
<p>Inny przykład:</p>
<pre class="brush: java;">
public class FinderTest extends TestCase {

    public void testFind() {
        Finder mock = createMock(Finder.class);
        expect(mock.find(&quot;Lucy&quot;, aryEq(new String[] {&quot;Amy&quot;, &quot;Luke&quot;}))).andReturn(
            Collections.EMPTY_LIST);
        replay(mock);

        List&lt;String&gt; list = mock.find(&quot;Lucy&quot;, new String[] {&quot;Amy&quot;, &quot;Luke&quot;});
        assertTrue(list.isEmpty());
    }
}
</pre>
<p>Warto zwrócić uwagę na to, że jeśli korzystamy dla matchera aby dopasować argument to musimy zrobić to dla wszystkich, inaczej poleci wyjątek:</p>
<pre class="brush: java;">
java.lang.IllegalStateException: 2 matchers expected, 1 recorded.
</pre>
<p>Stąd nasz test w końcowej postaci powinien wyglądać następująco:</p>
<pre class="brush: java;">
package org.code_house.test.mock;

import static org.easymock.EasyMock.aryEq;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;

import java.util.Collections;
import java.util.List;

import junit.framework.TestCase;

interface Finder {
    List&lt;String&gt; find(String[] names);

    List&lt;String&gt; find(String name, String[] names);
}

public class FinderTest extends TestCase {

    public void testFind() {
        Finder mock = createMock(Finder.class);
        expect(mock.find(eq(&quot;Lucy&quot;), aryEq(new String[] {&quot;Amy&quot;, &quot;Luke&quot;}))).andReturn(
            Collections.EMPTY_LIST);
        replay(mock);

        List&lt;String&gt; list = mock.find(&quot;Lucy&quot;, new String[] {&quot;Amy&quot;, &quot;Luke&quot;});
        assertTrue(list.isEmpty());
    }
}
</pre>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2008/11/26/testing-array-parameters-with-easymock/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Uruchom inny język w Javie</title>
		<link>http://blog.dywicki.pl/2008/11/24/scripting-inside-java/</link>
		<comments>http://blog.dywicki.pl/2008/11/24/scripting-inside-java/#comments</comments>
		<pubDate>Mon, 24 Nov 2008 06:00:02 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Porady]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=236</guid>
		<description><![CDATA[Do Javy 6.0 zostało dołączone API (JSR 223) umożliwiające wywoływanie różnych języków wewnątrz wirtualnej maszyny. Można w ten sposób przesunąć chociażby moment kompilowania kodu na później bądź od razu podpiąć język interpretowany. Poniżej przykład: package org.code_house.scripting; import javax.script.ScriptEngine; import javax.script.ScriptEngineFactory; import javax.script.ScriptEngineManager; public class JSMain { public static void main(String[] args) throws Exception { ScriptEngineManager [...]]]></description>
				<content:encoded><![CDATA[<p>Do Javy 6.0 zostało dołączone <acronym title="Application Programming Interface">API</acronym> (<a href="http://www.jcp.org/en/jsr/detail?id=223">JSR 223</a>) umożliwiające wywoływanie różnych języków wewnątrz wirtualnej maszyny. Można w ten sposób przesunąć chociażby moment kompilowania kodu na później bądź od razu podpiąć język interpretowany.<br />
<span id="more-236"></span><br />
Poniżej przykład:</p>
<pre class="brush: java;">
package org.code_house.scripting;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;


public class JSMain {

    public static void main(String[] args) throws Exception {
        ScriptEngineManager manager = new ScriptEngineManager();

        System.out.println(&quot;Dostępne języki&quot;);
        for (ScriptEngineFactory engine : manager.getEngineFactories()) {
            System.out.println(engine.getNames());
        }

        ScriptEngine engine = manager.getEngineByName(&quot;js&quot;);
        engine.put(&quot;y&quot;, 12);

        if (engine != null) {
            engine.eval(&quot;var x = 1; print(x + y);&quot;);
        }
    }

}
</pre>
<p>W taki oto sposób na naszej konsoli powinno wylądować coś takiego:</p>
<pre class="brush: java;">
[js, rhino, JavaScript, javascript, ECMAScript, ecmascript]
13
</pre>
<p>
<img src="http://blog.dywicki.pl/wp-content/uploads/2008/11/js-swing.jpg" alt="Swing + Java Script" title="Swing + Java Script" width="180" height="80" align="right" /></p>
<p>Możemy również uruchomić plik js. Wystarczy do metody <b>eval</b> przekazać FileReader. Po uruchomieniu kodu który jest niżej powinno pokazać się okienko podobne do tego, które widzicie przy tym akapicie.
</p>
<pre class="brush: java;">package org.code_house.scripting;

import java.io.*;
import javax.script.*;

public class JavaScriptMain {
    public static void main(String[] args) throws Exception {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName(&quot;js&quot;);
        engine.eval(new FileReader(new File(&quot;print.js&quot;)));
    }
}</pre>
<pre class="brush: jscript;">
frame = new javax.swing.JFrame;
frame.defaultCloseOperation = javax.swing.JFrame.EXIT_ON_CLOSE;
frame.title = &quot;Test&quot;
frame.setSize(new java.awt.Dimension(180, 80));

button = new javax.swing.JButton(&quot;Kliknij mnie&quot;)
button.addActionListener(function(event) {
    print(event.source);
});
frame.add(button);

frame.show()
</pre>
<p>Z dodatkowych języków można podpiąć między innymi <a href="http://php.net"><acronym title="Pre-Hypertext Processing">PHP</acronym></a>, <a href="http://java.sun.com/javafx/">Java FX</a>, <a href="http://groovy.codehaus.org">Groovy</a>, <a href="http://www.beanshell.org/">BeanShell</a> i wiele innych. Aby to zrobić należy ściągnąć ze strony <a href="https://scripting.dev.java.net/">scripting.dev.java.net</a> rozszerzenia (dostępne w sekcji Documents &#038; files) i dodać JAR dla języka którego potrzebujemy do classpath.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2008/11/24/scripting-inside-java/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Interfejs InitializingBean</title>
		<link>http://blog.dywicki.pl/2008/11/21/interfejs-initializingbean/</link>
		<comments>http://blog.dywicki.pl/2008/11/21/interfejs-initializingbean/#comments</comments>
		<pubDate>Fri, 21 Nov 2008 06:00:27 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Porady]]></category>
		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=235</guid>
		<description><![CDATA[Każdy z obiektów który jest konfigurowany w kontekście Springa ma szansę zweryfikować swój stan tuż po zainicjowaniu wszystkich wartości, które zostały mu przekazane. Wynika to z tego, że czasami obiekty potrafią działać na kilku różnych zasobach i można wstrzyknąć do nich tylko jeden rodzaj tegoż. Czasami po prostu potrzebujemy sprawdzić czy są przekazane wszystkie ustawienia [...]]]></description>
				<content:encoded><![CDATA[<p>Każdy z obiektów który jest konfigurowany w kontekście Springa ma szansę zweryfikować swój stan tuż po zainicjowaniu wszystkich wartości, które zostały mu przekazane. Wynika to z tego, że czasami obiekty potrafią działać na kilku różnych zasobach i można wstrzyknąć do nich tylko jeden rodzaj tegoż. Czasami po prostu potrzebujemy sprawdzić czy są przekazane wszystkie ustawienia konfiguracyjne bądź zainicjować połączenie do bazy danych na podstawie przekazanych parametrów.<br />
<span id="more-235"></span><br />
Mamy wówczas do wyboru dwie metody. Pierwszą z nich jest implementacja interfejsu <a href="http://www.docjar.com/docs/api/org/springframework/beans/factory/InitializingBean.html">org.springframework.beans.factory.InitializingBean</a>. Jeśli wyrzuci ona jakiś wyjątek to Spring wyrzuci wyjątek wyżej i wstrzyma powoływanie kontekstu. Oto przykład:</p>
<pre class="brush: java;">
package org.code_house.samples.spring;

import java.util.Properties;

import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.InitializingBean;

public class PropertiesConfiguration implements InitializingBean {

    /**
     * Ustawienia konfiguracyjne.
     */
    private Properties properties;

    public void setProperties(Properties props) {
        this.properties = props;
    }

    public void afterPropertiesSet() throws Exception {
        if (properties == null) {
            throw new BeanInitializationException(&quot;Nie przekazano ustawień &quot;
                +&quot;konfiguracyjnych. Pole properties jest wymagane.&quot;);
        }
    }
}
</pre>
<p>Spring nie wymusza jednak implementowania interfejsu. Jeśli nasz kod już istnieje i jest metoda która weryfikuje stan obiektu możemy użyć atrybutu init-method dla znacznika bean:</p>
<pre class="brush: xml;">
    &lt;bean class=&quot;org.code_house.samples.xml.JaxbConfiguration&quot;
        init-method=&quot;verify&quot;&gt;
        &lt;property name=&quot;source&quot; value=&quot;classpath:data.xml&quot; /&gt;
    &lt;/bean&gt;
</pre>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2008/11/21/interfejs-initializingbean/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Odwołanie do klasy Properties w kontekście springa</title>
		<link>http://blog.dywicki.pl/2008/11/20/odwolanie-do-klasy-properties-w-kontekscie-springa/</link>
		<comments>http://blog.dywicki.pl/2008/11/20/odwolanie-do-klasy-properties-w-kontekscie-springa/#comments</comments>
		<pubDate>Thu, 20 Nov 2008 06:00:46 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Porady]]></category>
		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=233</guid>
		<description><![CDATA[Jako, że nie zawsze mam czas pisać dłuższe noty, a nie wszyscy znają Springa postanowiłem publikować krótkie porady, które mogą kiedyś komuś się przydać. Klasa java.util.Properties to jeden z najprostszych sposobów na odwołanie do prostych ustawień konfiguracyjnych. Składnia pliku properties jest zbliżona do ini i wygląda następująco: nazwa.wlasnosci wartosc inna.nazwa.wlasnosci=costam # to jest komentarz jeszcze.cos.nowego [...]]]></description>
				<content:encoded><![CDATA[<p><em>Jako, że nie zawsze mam czas pisać dłuższe noty, a nie wszyscy znają Springa postanowiłem publikować krótkie porady, które mogą kiedyś komuś się przydać.</em><br />
<span id="more-233"></span><br />
Klasa java.util.Properties to jeden z najprostszych sposobów na odwołanie do prostych ustawień konfiguracyjnych. Składnia pliku properties jest zbliżona do ini i wygląda następująco:</p>
<p>nazwa.wlasnosci wartosc<br />
inna.nazwa.wlasnosci=costam<br />
# to jest komentarz<br />
jeszcze.cos.nowego</p>
<p>Jeśli chcemy przekazać obiekt klasy Properties do jakiegoś innego obiektu możemy skorzystać z poniższej wstawki w kontekście springa:</p>
<pre class="brush: xml;">
&lt;bean class=&quot;org.springframework.beans.factory.config.PropertiesFactoryBean&quot;&gt;
    &lt;property name=&quot;location&quot; value=&quot;classpath:corba.properties&quot; /&gt;
&lt;/bean&gt;
</pre>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2008/11/20/odwolanie-do-klasy-properties-w-kontekscie-springa/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Jeśli coś nie jest komercyjne nie jest też profesjonalne</title>
		<link>http://blog.dywicki.pl/2008/11/19/jesli-cos-nie-jest-komercyjne-nie-jest-tez-profesjonalne/</link>
		<comments>http://blog.dywicki.pl/2008/11/19/jesli-cos-nie-jest-komercyjne-nie-jest-tez-profesjonalne/#comments</comments>
		<pubDate>Wed, 19 Nov 2008 09:22:43 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Inne]]></category>
		<category><![CDATA[ServiceMix]]></category>
		<category><![CDATA[Śmieci]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=232</guid>
		<description><![CDATA[Ostatnimi czasy odbyłem kilka spotkań w większych i mniejszych firmach. To co mnie zastanowiło po jednej z ostatniej rozmów to zdanie: Korzystamy z profesjonalnych narzędzi takich jak Tibco, WebMethods, czasami Bea. Co łączy wymienione produkty? Otóż wszystkie są rozwiązaniami z klasy EAI i &#8230; są płatne. Zdanie to usłyszałem w odniesieniu do Apache Service Mix, [...]]]></description>
				<content:encoded><![CDATA[<p>Ostatnimi czasy odbyłem kilka spotkań w większych i mniejszych firmach. To co mnie zastanowiło po jednej z ostatniej rozmów to zdanie:</p>
<blockquote><p>Korzystamy z profesjonalnych narzędzi takich jak <a href="http://www.tibco.com/">Tibco</a>, <a href="http://www.softwareag.com/Corporate/products/wm/default.asp">WebMethods</a>, czasami <a href="http://www.bea.com/framework.jsp?CNT=index.htm&#038;FP=/content/products/aqualogic/service_bus/">Bea</a>.</p></blockquote>
<p>Co łączy wymienione produkty? Otóż wszystkie są rozwiązaniami z klasy EAI i &#8230; są płatne. Zdanie to usłyszałem w odniesieniu do <a href="http://servicemix.apache.org">Apache Service Mix</a>, którym się interesuję. Wniosek z tej wypowiedzi jaki udało mi się wysnuć od razu stał się tematem tej noty, czyli jeśli coś nie jest komercyjne nie jest też profesjonalne. Tak jakby <acronym title="Open Source Software">OSS</acronym> był gorszym rozwiązaniem od kupienia licencji na pudełkowe rozwiązanie od jakiegoś producenta.<br />
<span id="more-232"></span><br />
Trudno mi się z tym zgodzić ponieważ od początku swojej pracy obracam się w otwartym kodzie i niejeden raz korzystałem z wolnodostępnych narzędzi. Pamiętam jedną z sytuacji, gdzie w jednej z bardzo dużych międzynarodowych firm projekt przez pracowników był uważany za profesjonalny ponieważ był kupiony Oracle oraz licencja na jakiś przestarzały serwer. Kuriozalne, im więcej wydasz pieniędzy na licencję tym bardziej projekt jest profesjonalny. Klient dopiero wydając masę pieniędzy na licencję ma prawo powiedzieć, że kupił profesjonalny, będący na wysokim poziomie, produkt.</p>
<p>Zainspirowany tym wszystkim sięgnąłem do <a href="http://sjp.pwn.pl/">słownika języka polskiego PWN</a> w poszukiwania hasła <a href="http://sjp.pwn.pl/haslo.php?id=2508549">profesjonalny</a>:</p>
<blockquote><p>profesjonalny<br />
1. będący specjalistą w jakiejś dziedzinie<br />
2. uprawiany jako zawód<br />
3. będący na wysokim poziomie w danej dziedzinie<br />
4. spełniający wymagania profesjonalistów
</p></blockquote>
<p>Definicja słownikowa nie wspomina nic o pieniądzach, ale dodajmy ją w myśl pierwszego, zacytowanego zdania:<br />
1. Jeśli chcesz być specjalistą w jakiejś dziedzinie musisz korzystać z komercyjnych rozwiązań.<br />
3. Wysoki poziom w danej dziedzinie osiągniesz korzystając tylko z komercyjnych produktów.<br />
4. Produkt jest profesjonalny jeśli spełnia wymagania profesjonalistów, a jednym z kryteriów doboru tego narzędzia zgodnie z punktem 1 jest płatność.</p>
<p>Czy zgadzacie się z takimi założeniami? Ja &#8211; w ogóle. Nie jestem maniakiem Open Source ani fanatykiem wolnego oprogramowania. Nie jestem też nadmiernym zwolennikiem komercyjnych rozwiązań, ale to co powinno być kluczowe dla każdego programisty a tym bardziej firmy świadczącej usługi programistyczne to szukanie skutecznego rozwiązania problemu a nie wydania pieniędzy.</p>
<p>Reasumując, moje zdanie to:</p>
<ul>
<li>Nie wszędzie pasuje <acronym title="Open Source Software">OSS</acronym>.</li>
<li>Nie wszędzie konieczne są rozwiązania komercyjne.</li>
<li>Nie zawsze nabycie produktu rozwiązuje wszystkie problemy. Czasami rodzi też nowe.</li>
</ul>
<p>Warto zwrócić uwagę na to, że producenci oprogramowania czasami mamią i zarzucają nas całą masą marketingu, hasłami i wszelakimi buzzworld typu <acronym title="Service Oriented Architecture">SOA</acronym>, <acronym title="Asynchronous JavaScript and XML">AJAX</acronym> itp. podczas gdy rozwiązania oparte na <acronym title="Open Source Software">OSS</acronym> nie są reklamowane, a zdarza się sytuacje że mają funkcjonalność zbliżoną bądź nawet większą niż komercyjne.</p>
<p>Jakie jest, drodzy czytelnicy, wasze zdanie na temat &#8211; czy <acronym title="Open Source Software">OSS</acronym> może być profesjonalny? Co czyni produkt profesjonalnym?</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2008/11/19/jesli-cos-nie-jest-komercyjne-nie-jest-tez-profesjonalne/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
