<?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 &#187; JAXB</title>
	<atom:link href="http://blog.dywicki.pl/category/jaxb/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</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
		<item>
		<title>Budowanie usługi sieciowej w oparciu o Apache CXF</title>
		<link>http://blog.dywicki.pl/2008/07/23/budowanie-uslugi-sieciowej-w-oparciu-o-apache-cxf/</link>
		<comments>http://blog.dywicki.pl/2008/07/23/budowanie-uslugi-sieciowej-w-oparciu-o-apache-cxf/#comments</comments>
		<pubDate>Wed, 23 Jul 2008 06:27:55 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[CXF]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JAXB]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=219</guid>
		<description><![CDATA[Od jakiegoś czasu w pracy do tworzenia usług sieciowych korzystam z Apache CXF. Jako że biblioteka jest stosunkowo nowa i nie najlepiej udokumentowana postanowiłem przedstawić na blogu jak wygląda proces tworzenia. CXF jest połączeniem kilku bibliotek - YOKO, Celtixa oraz XFire. Każda z nich wcześniej realizowała pewien fragment obecnej funkcjonalności CXF - YOKO obsługuje Corbę [...]]]></description>
			<content:encoded><![CDATA[<p>Od jakiegoś czasu w pracy do tworzenia usług sieciowych korzystam z <a href="http://cxf.apache.org">Apache CXF</a>. Jako że biblioteka jest stosunkowo nowa i nie najlepiej udokumentowana postanowiłem przedstawić na blogu jak wygląda proces tworzenia.</p>
<p>CXF jest połączeniem kilku bibliotek - <a href="http://cwiki.apache.org/YOKO/">YOKO</a>, <a href="http://celtix.objectweb.org/">Celtixa</a> oraz <a href="http://xfire.codehaus.org/">XFire</a>. Każda z nich wcześniej realizowała pewien fragment obecnej funkcjonalności CXF - YOKO obsługuje Corbę a XFire usługi sieciowe. Obecne CXF jest gotowy do używania "produkcyjnego", ponieważ niedawno wyszedł z fazy inkubacji. :)<br />
<span id="more-219"></span></p>
<h3>Architektura</h3>
<p>CXF ma dosyć elastyczną budowę. Zgodnie z <a href="http://cwiki.apache.org/CXF20DOC/cxf-architecture.html">dokumentacją</a> można wyróżnić najważniejsze składowe:</p>
<ul>
<li><b>Bus</b>, jest trzonem architektury CXF w którym definiuje i konfiguruje się rozszerzenia.</li>
<li><b>Messaging &#038; Interceptors</b>, zapewniają niskopoziomowy dostęp do komunikatów oraz warstwę na której jest oparta większość funkcjonalności.</li>
<li><b>Front ends</b>, frontendy są interfejsami programistycznymi do tworzenia usług (np. JAX-WS).</li>
<li><b>Services</b>, usługi zapewniają model wraz z opisem</li>
<li><b>Bidings</b>, element ten jest odpowiedzialny za obsługę konkretnego protokołu (<acronym title="Simple Object Access Protocol">SOAP</acronym>, REST, Corba etc).</li>
<li><b>Transports</b>, warstwa abstrakcji ułatwiająca zmianę sposobu transportu do/z usług.</li>
</ul>
<h3>Markieting :)</h3>
<p>CXF oferuje infrastrukturę konieczną do budowania usług, z najważniejszy zalet można wymienić:</p>
<ul>
<li>Wsparcie dla różnych protokołów.</li>
<li>Obsługa standardów WS-*, tj. WS-Addressing, WS-Security, WS-ReliableMessaging, oraz WS-Policy.</li>
<li>Obsługa wielu transportów.</li>
<li>Dołączane data-bindingi (np JAXB, Aegis).</li>
<li>Jasny podział front endów takich jak JAX-WS od najważniejszego kodu.</li>
<li>Wysoka wydajność.</li>
<li>Możliwość osadzania w różnych środowiskach.</li>
</ul>
<p>Z dodatkowych zalet, mogę dodać - bardzo łatwą integrację ze Springiem.</p>
<h2>Pierwsza usługa</h2>
<p>Do budowania projektów będziemy używać <a href="http://maven.apache.org">Mavena</a>. Implementowana usługa będzie oparta o frontend JAX-WS z ręcznie pisanym deskryptorem usługi (<acronym title="Web Services Description Language">WSDL</acronym> first). Jakkolwiek w bardzo prosty sposób można odwrócić kolejność i przy pomocy pluginu CXF do Mavena wygenerować deskryptor.</p>
<p>Struktura projektów będzie następująca:</p>
<ul>
<li>parent<br />
         Rodzic projektu ze zdefiniowanymi wersjami bibliotek i raportami.
    </li>
<ul>
<li>contract<br />
             Definicje używane zarówno przez klienta jak i serwer - <acronym title="Web Services Description Language">WSDL</acronym> oraz konfiguracja pluginu CXF.</li>
<li>client<br />
             Prosta biblioteka kliencka oparta o mechanizmy CXFa (JaxWSProxyFactoryBean).</li>
<li>server<br />
             Przykładowa implementacja usługi z bardzo prostym wykorzystaniem Springa.</li>
<li>webapp<br />
            Konfiguracja transporty CXF - w tym konkretnym przypadku servletu CXF.</li>
</ul>
</ul>
<h2>Parent</h2>
<p>Poniżej znajduje się deskryptor projektu, który jest używany do budowania całości.</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;project xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&gt;

    &lt;!-- Informacja dla Mavena --&gt;
    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;

    &lt;!-- Identyfikacja projektu --&gt;
    &lt;groupId&gt;org.code-house.cxf&lt;/groupId&gt;
    &lt;artifactId&gt;parent&lt;/artifactId&gt;
    &lt;name&gt;Code House.Org - CXF&lt;/name&gt;
    &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
    &lt;packaging&gt;pom&lt;/packaging&gt;

    &lt;description&gt;Rodzic projektu, zawiera wszystkie moduly.&lt;/description&gt;

    &lt;!-- Składowe projektu --&gt;
    &lt;modules&gt;
        &lt;module&gt;cxf-client&lt;/module&gt;
        &lt;module&gt;cxf-contract&lt;/module&gt;
        &lt;module&gt;cxf-server&lt;/module&gt;
        &lt;module&gt;cxf-webapp&lt;/module&gt;
    &lt;/modules&gt;

    &lt;!-- Definicje zmiennych dostępne również w modułach --&gt;
    &lt;properties&gt;
        &lt;code-house.cxf.version&gt;2.1.1&lt;/code-house.cxf.version&gt;
        &lt;code-house.jaxb.version&gt;2.1.3&lt;/code-house.jaxb.version&gt;
        &lt;code-house.spring.version&gt;2.5.4&lt;/code-house.spring.version&gt;
    &lt;/properties&gt;

    &lt;build&gt;
        &lt;plugins&gt;
            &lt;!-- Konfiguracja kompilatora --&gt;
            &lt;plugin&gt;
                &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
                &lt;configuration&gt;
                    &lt;source&gt;1.5&lt;/source&gt;
                    &lt;target&gt;1.5&lt;/target&gt;
                &lt;/configuration&gt;
            &lt;/plugin&gt;
        &lt;/plugins&gt;
    &lt;/build&gt;

    &lt;reporting&gt;
    &lt;!--Wycięte :) --&gt;
    &lt;/reporting&gt;

    &lt;!-- Predefiniowane wersje bibliotek --&gt;
    &lt;dependencyManagement&gt;
        &lt;dependencies&gt;
            &lt;dependency&gt;
                &lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;
                &lt;artifactId&gt;cxf-rt-frontend-jaxws&lt;/artifactId&gt;
                &lt;version&gt;${code-house.cxf.version}&lt;/version&gt;
            &lt;/dependency&gt;
            &lt;dependency&gt;
                &lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;
                &lt;artifactId&gt;cxf-rt-transports-http&lt;/artifactId&gt;
                &lt;version&gt;${code-house.cxf.version}&lt;/version&gt;
            &lt;/dependency&gt;
            &lt;dependency&gt;
                &lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;
                &lt;artifactId&gt;cxf-rt-transports-http-jetty&lt;/artifactId&gt;
                &lt;version&gt;${code-house.cxf.version}&lt;/version&gt;
            &lt;/dependency&gt;
            &lt;dependency&gt;
                &lt;groupId&gt;com.sun.xml.bind&lt;/groupId&gt;
                &lt;artifactId&gt;jaxb-impl&lt;/artifactId&gt;
                &lt;version&gt;${code-house.jaxb.version}&lt;/version&gt;
            &lt;/dependency&gt;
            &lt;dependency&gt;
                &lt;groupId&gt;javax.xml.bind&lt;/groupId&gt;
                &lt;artifactId&gt;jaxb-api&lt;/artifactId&gt;
                &lt;version&gt;2.1&lt;/version&gt;
            &lt;/dependency&gt;
        &lt;/dependencies&gt;
    &lt;/dependencyManagement&gt;

&lt;/project&gt;
</pre>
<h2>Contract</h2>
<p>Zgodnie z tym, co napisałem wcześniej - przyjąłem podejście, że <acronym title="Web Services Description Language">WSDL</acronym> jest pisany ręcznie, głównie dlatego że dla większych projektów można w prosty sposób narzucić jakąś organizację i podział plików, z których są następnie generowane źródła.<br />
Najistotniejsza wstawka, która powinna znaleźć się w pomie:</p>
<pre class="brush: xml;">
&lt;!-- Generowanie kodu z deskryptora <acronym title="Web Services Description Language">WSDL</acronym> --&gt;
&lt;plugin&gt;
    &lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;
    &lt;artifactId&gt;cxf-codegen-plugin&lt;/artifactId&gt;
    &lt;executions&gt;
        &lt;execution&gt;
            &lt;phase&gt;generate-sources&lt;/phase&gt;
            &lt;configuration&gt;
                &lt;sourceRoot&gt;${basedir}/target/jaxws&lt;/sourceRoot&gt;
                &lt;wsdlOptions&gt;
                    &lt;wsdlOption&gt;
                        &lt;wsdl&gt;
                            ${basedir}/src/main/resources/maven.wsdl
                        &lt;/wsdl&gt;
                        &lt;extraargs&gt;
                            &lt;extraarg&gt;-quiet&lt;/extraarg&gt;
                        &lt;/extraargs&gt;
                    &lt;/wsdlOption&gt;
                &lt;/wsdlOptions&gt;
            &lt;/configuration&gt;
            &lt;goals&gt;
                &lt;goal&gt;wsdl2java&lt;/goal&gt;
            &lt;/goals&gt;
        &lt;/execution&gt;
    &lt;/executions&gt;
&lt;/plugin&gt;
</pre>
<p>Po dodaniu tej wstawki do sekcji <b>build/plugins</b> możemy przejść do tworzenia deskryptora usługi. W moim przypadku przyjąłem następujący podział:</p>
<ol>
<li>maven.wsdl - definicje metod oraz komunikatów w rozumieniu <acronym title="Web Services Description Language">WSDL</acronym> (messages). Można z powodzeniem wyłączyć z tego pliku same koperty i pozostawić metody a to co potrzebne włączyć dyrektywą <b>wsdl:import</b>.</li>
<li>types.xsd - typy używane do komunikacji - zazwyczaj pary request+response używane bezpośrednio w definiowaniu elementów <b>wsdl:part</b>.</li>
<li>definition.xsd - definicje typów złożonych, niezależnych od usług, tj. opis domain-modelu z którym usługa pracuje.</li>
</ol>
<p>Każdy z tych plików ma inną przestrzeń nazw.</p>
<h3>maven.wsdl</h3>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;wsdl:definitions xmlns:soap=&quot;http://schemas.xmlsoap.org/wsdl/soap/&quot;
    xmlns:tns=&quot;http://code-house.org/services/maven&quot;
    xmlns:types=&quot;http://code-house.org/services/maven/types&quot;
    xmlns:wsdl=&quot;http://schemas.xmlsoap.org/wsdl/&quot;
    xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;
    targetNamespace=&quot;http://code-house.org/services/maven&quot;
    name=&quot;MavenServices&quot;
    &gt;

    &lt;wsdl:types&gt;
        &lt;xsd:schema targetNamespace=&quot;http://code-house.org/services/maven/types&quot;&gt;
            &lt;xsd:include schemaLocation=&quot;types.xsd&quot; /&gt;
        &lt;/xsd:schema&gt;
    &lt;/wsdl:types&gt;

    &lt;wsdl:message name=&quot;findArtifactRequest&quot;&gt;
        &lt;wsdl:part name=&quot;request&quot; type=&quot;types:FindArtifactRequest&quot; /&gt;
    &lt;/wsdl:message&gt;
    &lt;wsdl:message name=&quot;findArtifactResponse&quot;&gt;
        &lt;wsdl:part name=&quot;response&quot; type=&quot;types:FindArtifactRespose&quot; /&gt;
    &lt;/wsdl:message&gt;

    &lt;wsdl:portType name=&quot;MavenArtifactType&quot;&gt;
        &lt;wsdl:operation name=&quot;findArtifact&quot;&gt;
            &lt;wsdl:input message=&quot;tns:findArtifactRequest&quot; /&gt;
            &lt;wsdl:output message=&quot;tns:findArtifactResponse&quot; /&gt;
        &lt;/wsdl:operation&gt;
    &lt;/wsdl:portType&gt;

    &lt;wsdl:binding name=&quot;MavenArtifactSOAP&quot; type=&quot;tns:MavenArtifactType&quot;&gt;
        &lt;soap:binding style=&quot;document&quot; transport=&quot;http://schemas.xmlsoap.org/soap/http&quot; /&gt;
        &lt;wsdl:operation name=&quot;findArtifact&quot;&gt;
            &lt;wsdl:input&gt;
                &lt;soap:body use=&quot;literal&quot; /&gt;
            &lt;/wsdl:input&gt;
            &lt;wsdl:output&gt;
                &lt;soap:body use=&quot;literal&quot; /&gt;
            &lt;/wsdl:output&gt;
        &lt;/wsdl:operation&gt;
    &lt;/wsdl:binding&gt;

    &lt;wsdl:service name=&quot;MavenServices&quot;&gt;
        &lt;wsdl:port binding=&quot;tns:MavenArtifactSOAP&quot; name=&quot;Maven Services&quot;&gt;
            &lt;soap:address location=&quot;http://localhost:8080/webapp/services/maven&quot; /&gt;
        &lt;/wsdl:port&gt;
    &lt;/wsdl:service&gt;
&lt;/wsdl:definitions&gt;
</pre>
<h3>types.xsd</h3>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;schema xmlns=&quot;http://www.w3.org/2001/XMLSchema&quot;
    targetNamespace=&quot;http://code-house.org/services/maven/types&quot;
    xmlns:tns=&quot;http://code-house.org/services/maven/types&quot;
    xmlns:def=&quot;http://code-house.org/services/maven/definition&quot;
    elementFormDefault=&quot;qualified&quot;&gt;

    &lt;import schemaLocation=&quot;definition.xsd&quot;
        namespace=&quot;http://code-house.org/services/maven/definition&quot; /&gt;

    &lt;complexType name=&quot;FindArtifactRequest&quot;&gt;
        &lt;sequence&gt;
            &lt;element name=&quot;query&quot; type=&quot;def:ArtifactInfo&quot; /&gt;
        &lt;/sequence&gt;
    &lt;/complexType&gt;

    &lt;complexType name=&quot;FindArtifactRespose&quot;&gt;
        &lt;sequence&gt;
            &lt;element name=&quot;downloadURL&quot; type=&quot;anyURI&quot; /&gt;
        &lt;/sequence&gt;
    &lt;/complexType&gt;

&lt;/schema&gt;
</pre>
<h3>definition.xsd</h3>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;schema xmlns=&quot;http://www.w3.org/2001/XMLSchema&quot;
    targetNamespace=&quot;http://code-house.org/services/maven/definition&quot;
    xmlns:tns=&quot;http://code-house.org/services/maven/definition&quot;
    elementFormDefault=&quot;qualified&quot;&gt;

    &lt;complexType name=&quot;ArtifactInfo&quot;&gt;
        &lt;sequence&gt;
            &lt;element name=&quot;groupId&quot; type=&quot;string&quot; /&gt;
            &lt;element name=&quot;artifactId&quot; type=&quot;string&quot; /&gt;
            &lt;element name=&quot;version&quot; type=&quot;string&quot; minOccurs=&quot;0&quot; /&gt;
            &lt;element name=&quot;classifier&quot; type=&quot;tns:Classifier&quot; minOccurs=&quot;0&quot; /&gt;
            &lt;element name=&quot;packaging&quot; type=&quot;tns:Packaging&quot; minOccurs=&quot;0&quot; /&gt;
            &lt;element name=&quot;type&quot; type=&quot;tns:Type&quot; minOccurs=&quot;0&quot; /&gt;
        &lt;/sequence&gt;
    &lt;/complexType&gt;

    &lt;simpleType name=&quot;Type&quot;&gt;
        &lt;restriction base=&quot;string&quot;&gt;
            &lt;enumeration value=&quot;dll&quot; /&gt;
            &lt;enumeration value=&quot;so&quot; /&gt;
        &lt;/restriction&gt;
    &lt;/simpleType&gt;

    &lt;simpleType name=&quot;Classifier&quot;&gt;
        &lt;restriction base=&quot;string&quot;&gt;
            &lt;enumeration value=&quot;sources&quot; /&gt;
            &lt;enumeration value=&quot;javadoc&quot; /&gt;
            &lt;enumeration value=&quot;resources&quot; /&gt;
        &lt;/restriction&gt;
    &lt;/simpleType&gt;

    &lt;simpleType name=&quot;Packaging&quot;&gt;
        &lt;restriction base=&quot;string&quot;&gt;
            &lt;enumeration value=&quot;pom&quot; /&gt;
            &lt;enumeration value=&quot;jar&quot; /&gt;
            &lt;enumeration value=&quot;war&quot; /&gt;
            &lt;enumeration value=&quot;bundle&quot; /&gt;
        &lt;/restriction&gt;
    &lt;/simpleType&gt;

&lt;/schema&gt;
</pre>
<p>Po odpaleniu polecenia <b>mvn:install</b> powinniśmy otrzymać w konsoli fragment podobny do tego:</p>
<pre class="brush: plain;">
[INFO] [cxf-codegen:wsdl2java {execution: default}]
</pre>
<p>Jest to informacja, że plugin CXF został poprawnie skonfigurowany i uruchomiony.</p>
<h2>Serwer</h2>
<p>Sercem naszej usługi jest oczywiście jej implementacja dlatego też nie możemy obejść się bez niej. :) Projekt ten ma tylko dwie zależności - <b>contract</b> oraz artefakt <b>cxf-rt-frontend-jaxws</b>.</p>
<p>Konfiguracja serwera odbywa się w oparciu o springa:</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
    xmlns:jaxws=&quot;http://cxf.apache.org/jaxws&quot;
    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
    xsi:schemaLocation=&quot;

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

http://cxf.apache.org/jaxws

http://cxf.apache.org/schemas/jaxws.xsd

    &quot;&gt;

    &lt;!-- Dodatkowy bean zawierający właściwą implementację logiki związanej z wyszukiwaniem --&gt;
    &lt;bean id=&quot;service&quot; class=&quot;org.code_house.services.maven.DummyMavenSearchServiceImpl&quot; /&gt;

    &lt;!-- Bean będący implementacją usługi jako takiej - obsługujący wejście/wyjście --&gt;
    &lt;bean id=&quot;mavenService&quot; class=&quot;org.code_house.services.maven.MavenArtifactTypeImpl&quot;&gt;
        &lt;property name=&quot;service&quot; ref=&quot;service&quot; /&gt;
    &lt;/bean&gt;

    &lt;!-- Konfiguracja endpointu CXFa --&gt;
    &lt;jaxws:endpoint address=&quot;maven&quot; id=&quot;jaxwsMavenService&quot; implementor=&quot;#mavenService&quot; /&gt;

&lt;/beans&gt;
</pre>
<p>Serwer zawiera w zasadzie niewiele kodu, oto i on:</p>
<pre class="brush: java;">
package org.code_house.services.maven;

import java.net.URISyntaxException;

import javax.jws.WebService;

import org.code_house.services.maven.definition.ArtifactInfo;
import org.code_house.services.maven.types.FindArtifactRequest;
import org.code_house.services.maven.types.FindArtifactRespose;

/**
  * Implementacja usługi.
  */
@WebService(serviceName = &quot;MavenService&quot;,
    endpointInterface = &quot;org.code_house.services.maven.MavenArtifactType&quot;,
    targetNamespace = &quot;http://code-house.org/services/maven&quot;
)
public class MavenArtifactTypeImpl implements MavenArtifactType {

    /**
      * Bean zawierający implementację logiki biznesowej.
      */
    private MavenSearchService service;

    public FindArtifactRespose findArtifact(FindArtifactRequest request) {
        ArtifactInfo info = request.getQuery(); // pobranie struktury przekazanej od klienta

        // sformuowanie odpowiedzi
        FindArtifactRespose response = new FindArtifactRespose();
        try {
            response.setDownloadURL(service.find(info).toURI().toString());
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
        return response;
    }

    /**
     * Ustawienie wartości pola service.
     *
     * @param service Nowa wartość pola service.
     */
    public void setService(MavenSearchService service) {
        this.service = service;
    }
}
</pre>
<p>Dodatkowy kod, który nie jest konieczny do implementacji usługi to definicja interfejsu <b>MavenSearchService</b>. Dzięki zastosowaniu takiego rozwiązania można w prostszy sposób testować działanie usługi poprzez przekazywanie jej mocka stworzonego np. przy pomocy <a href="http://easymock.org">easy mocka</a>. Kod takiego testu pominąłem ze względu na to, że notka i tak już jest za długa w tym momencie a jesteśmy ledwo w połowie drogi. :)</p>
<p>Przykładowa implementacja wcześniej wspomnianego intefejsu nie zawiera żadnej logiki i zawsze zwraca tą samą wartość.</p>
<pre class="brush: java;">
package org.code_house.services.maven;

import java.net.MalformedURLException;
import java.net.URL;

import org.code_house.services.maven.definition.ArtifactInfo;

// Najprostsza implementacja tylko po to żeby sprawdzić działanie usługi
public class DummyMavenSearchServiceImpl implements MavenSearchService {

    public <acronym title="Uniform Resource Locator">URL</acronym> find(ArtifactInfo info) {
        try {
            return new <acronym title="Uniform Resource Locator">URL</acronym>(&quot;http://repo1.maven.org/maven2/org/apache/apache/4/apache-4.pom&quot;);
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        }
    }

}
</pre>
<p>Zanim odpalimy serwer konieczna będzie jeszcze jedna rzecz - konfiguracja transporu, w naszym przypadku servletu CXF.</p>
<h2>Webapp</h2>
<p>Webapp posiada bezpośrednie zależności do 2 artefaktów CXFa: <b>cxf-rt-transports-http</b> oraz <b>cxf-rt-bindings-http</b>. Druga jest opcjonalna, bez niej CXF nie będzie wyświetlał dostępnych usług w postaci tabelki html.</p>
<p>Przydatna może być wtyczka jetty (sekcja <b>build/plugins</b>), która pozwala na uruchomienie aplikacji bez konieczności instalowania kontenera servletów:</p>
<pre class="brush: xml;">
&lt;plugin&gt;
    &lt;groupId&gt;org.mortbay.jetty&lt;/groupId&gt;
    &lt;artifactId&gt;maven-jetty-plugin&lt;/artifactId&gt;
    &lt;version&gt;6.1.11&lt;/version&gt;
    &lt;configuration&gt;
        &lt;scanIntervalSeconds&gt;10&lt;/scanIntervalSeconds&gt;
        &lt;connectors&gt;
            &lt;connector implementation=&quot;org.mortbay.jetty.nio.SelectChannelConnector&quot;&gt;
                &lt;port&gt;8080&lt;/port&gt;
                &lt;maxIdleTime&gt;60000&lt;/maxIdleTime&gt;
            &lt;/connector&gt;
        &lt;/connectors&gt;
    &lt;/configuration&gt;
&lt;/plugin&gt;
</pre>
<p>Ostatnia zależność odnosi się do implementacji usługi - czyli naszego artefaktu <b>server</b>. Najistotniejsze elementy konfiguracji webappa to web.xml oraz cxf-beans.xml.</p>
<h3>web.xml</h3>
<p>Warto zauważyć w poniższym listingu fajną możliwość, którą daje nam Spring w postaci wildcardów określających położenie konfiguracji - w tym przypadku <b>classpath:/module/*-context.xml</b>. Oznacza to, że Spring przeskanuje wszystkie biblioteki od których zależy projekt i dołączy ich konfigurację do głownej, dzięki czemu będziemy mogli uzyskać bardziej modułową i elastyczną budowę aplikacji. Może <a href="http://www.springframework.org/osgi">Dynamic Modules</a> to nie jest ale na codzień w zupełności wystarcza :).</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;web-app id=&quot;ocs&quot; version=&quot;2.5&quot;
    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
    xmlns=&quot;http://java.sun.com/xml/ns/javaee&quot;
    xmlns:web=&quot;http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot;
    xsi:schemaLocation=&quot;

http://java.sun.com/xml/ns/javaee

        http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot;
    &gt;

    &lt;!-- Informacje nazewnicze dla kontenera --&gt;
    &lt;display-name&gt;Maven Search Services :: Webapp&lt;/display-name&gt;
    &lt;description&gt;Frontend indeksera.&lt;/description&gt;

    &lt;!-- Lokalizacje plików konfiguracyjnych --&gt;
    &lt;context-param&gt;
        &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
        &lt;param-value&gt;
            &lt;!-- Konfiguracja zabezpieczeń opartych o spring secuirty --&gt;
            /WEB-INF/security.xml
            &lt;!-- Konfiguracja CXF --&gt;
            /WEB-INF/cxf-beans.xml
            &lt;!-- Konfiguracja kontekstu --&gt;
            /WEB-INF/applicationContext.xml
            &lt;!-- Wczytanie konfiguracji modułów --&gt;
            classpath:/module/*-context.xml
        &lt;/param-value&gt;
    &lt;/context-param&gt;

    &lt;!-- Servlet obsługujący usługi sieciowe --&gt;
    &lt;servlet&gt;
        &lt;servlet-name&gt;CXFServlet&lt;/servlet-name&gt;
        &lt;servlet-class&gt;org.apache.cxf.transport.servlet.CXFServlet&lt;/servlet-class&gt;
        &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
    &lt;/servlet&gt;

    &lt;!-- Mapowanie adresu usług sieciowych --&gt;
    &lt;servlet-mapping&gt;
        &lt;servlet-name&gt;CXFServlet&lt;/servlet-name&gt;
        &lt;url-pattern&gt;/services/*&lt;/url-pattern&gt;
    &lt;/servlet-mapping&gt;

    &lt;!-- Inicjowanie kontekstu springa --&gt;
    &lt;listener&gt;
        &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;
    &lt;/listener&gt;

&lt;/web-app&gt;
</pre>
<h3>cxf-beans.xml</h3>
<p>Plik ten zawiera definicje konfiguracyjne CXFa. W poniższej formie włączana jest tylko część modułów CXF w celu zmniejszenia użycia zasobów.</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
    xmlns:cxf=&quot;http://cxf.apache.org/core&quot;
    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
    xsi:schemaLocation=&quot;

http://cxf.apache.org/core

http://cxf.apache.org/schemas/core.xsd

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

    &quot;&gt;

    &lt;!-- Moduły CXF-a --&gt;
    &lt;import resource=&quot;classpath:META-INF/cxf/cxf.xml&quot;/&gt;
    &lt;import resource=&quot;classpath:META-INF/cxf/cxf-extension-soap.xml&quot;/&gt;
    &lt;import resource=&quot;classpath:META-INF/cxf/cxf-extension-http-binding.xml&quot;/&gt;
    &lt;import resource=&quot;classpath:META-INF/cxf/cxf-servlet.xml&quot;/&gt;

&lt;/beans&gt;
</pre>
<p>Pozostałe pliki konfiguracyjne są praktycznie puste, ponieważ tyczą się obszarów niezwiązanych z tematem tego wpisu. Po tym wszystkim możemy uruchomić naszą aplikację poleceniem <b>mvn jetty:run</b>. Po wejściu na adres http://localhost:8080/webapp/services naszym oczom powinna ukazać się lista podobna do poniższej:<br />
<img src="http://blog.dywicki.pl/wp-content/uploads/2008/07/services.jpg" alt="services" title="services" /><br />
Nie wiem niestety dlaczego CXF generuje zły adres usługi (pomijający mapowanie servletu) oraz ma problemy z wystawieniem WSDLa. Jakkolwiek i bez tego wszystko działa poprawnie - znaczy wywoływanie usług rzecz jasna. :)</p>
<p><a href="http://blog.dywicki.pl/wp-content/uploads/2008/07/soap-ui.jpg" style="text-decoration: none" rel="lightbox"><img src="http://blog.dywicki.pl/wp-content/uploads/2008/07/soap-ui-300x182.jpg" alt="soap-ui" title="soap-ui" width="300" height="182" align="right" /></a> W tym momencie możemy uruchomić <a href="http://www.soapui.org/">Soap UI</a> i wykonać jedyną dostępną metodę - findArtifact.</p>
<h2>Client</h2>
<p>Ostatnim z elementów, który pozostał do omówienia jest klient. Niestety z racji na to, że ta nota już się wystarczająco rozrosła zrobię to w kolejnym wpisie. Mam nadzieję, że nota ta nieco ułatwi przyszłym użytkownikom CXFa jego poznanie. :) Dla tych, którym nie chce się wpisywać tego wszystkiego w edytorze <a href="http://media.dywicki.pl/blog/cxf/cxf.zip">zamieszczam źródła</a> razem z działającym klientem. Projekty nie są nadzwyczajnie dopieszczone, ale w zupełności wystarczą do startu. Znajduje się też tam w pełni działający klient stworzonej usługi. Pozdrawiam i życzę miłej zabawy!</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2008/07/23/budowanie-uslugi-sieciowej-w-oparciu-o-apache-cxf/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>JAXB 2, zabawy z datą i konwersją typów</title>
		<link>http://blog.dywicki.pl/2008/05/17/jaxb-2-zabawy-z-data-i-konwersja-typow/</link>
		<comments>http://blog.dywicki.pl/2008/05/17/jaxb-2-zabawy-z-data-i-konwersja-typow/#comments</comments>
		<pubDate>Sat, 17 May 2008 09:10:27 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JAXB]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/2008/05/17/jaxb-2-zabawy-z-data-i-konwersja-typow/</guid>
		<description><![CDATA[Jedną z bolączek JAXB jest problematyczna obsługa dat i czasów. Przypomnijmy sobie schemat użyty w jednej z wcześniejszych not. &#60;!-- Definicja książki --&#62; &#60;complextype name=&#34;Book&#34;&#62; &#60;sequence&#62; &#60;element name=&#34;title&#34; type=&#34;string&#34; minOccurs=&#34;1&#34; /&#62; &#60;element name=&#34;isbn&#34; type=&#34;string&#34; /&#62; &#60;element name=&#34;releaseDate&#34; type=&#34;date&#34; /&#62; &#60;element name=&#34;author&#34; type=&#34;tns:Author&#34; maxOccurs=&#34;unbounded&#34; /&#62; &#60;/sequence&#62; &#60;/complextype&#62; Jak widać, każda książka ma określoną datę wydania. Jakkolwiek [...]]]></description>
			<content:encoded><![CDATA[<p>Jedną z bolączek JAXB jest problematyczna obsługa dat i czasów. Przypomnijmy sobie schemat użyty <a href="http://blog.dywicki.pl/?p=190">w jednej z wcześniejszych not</a>.<br />
<span id="more-192"></span></p>
<pre class="brush: xml;">

	&lt;!-- Definicja książki --&gt;
	&lt;complextype name=&quot;Book&quot;&gt;
		&lt;sequence&gt;
			&lt;element name=&quot;title&quot; type=&quot;string&quot; minOccurs=&quot;1&quot; /&gt;
			&lt;element name=&quot;isbn&quot; type=&quot;string&quot; /&gt;
			&lt;element name=&quot;releaseDate&quot; type=&quot;date&quot; /&gt;
			&lt;element name=&quot;author&quot; type=&quot;tns:Author&quot; maxOccurs=&quot;unbounded&quot; /&gt;
		&lt;/sequence&gt;
	&lt;/complextype&gt;
</pre>
<p>Jak widać, każda książka ma określoną datę wydania. Jakkolwiek typ date z <acronym title="eXtensible Markup Language">XML</acronym> Schema nie jest bezpośrednio odwzorowany do java.util.Date czy też java.util.Calendar. W przypadku implementacji dostarczonej przez Sun mamy do czynienia z obiektami klasy <a href="http://www.javaresearch.org/source/jdk150/com/sun/org/apache/xerces/internal/jaxp/datatype/XMLGregorianCalendarImpl.java.html">XMLGregorianCalendarImpl</a>. Rozwiązaniem problemu jest dodanie odpowiedniego adaptera. Możemy robić to ręcznie ale najwygodniejszym rozwiązaniem będzie skorzystanie z gotowca - klasy <a href="http://java.sun.com/webservices/docs/1.6/api/javax/xml/bind/DatatypeConverter.html">javax.xml.bind.DatatypeConverter</a>. Jej użycie wygląda następująco:</p>
<pre class="brush: xml;">&lt; ?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;schema xmlns=&quot;http://www.w3.org/2001/XMLSchema&quot; targetNamespace=&quot;http://dywicki.pl/court&quot;
    xmlns:jaxb=&quot;http://java.sun.com/xml/ns/jaxb&quot; jaxb:version=&quot;2.0&quot;
    xmlns:tns=&quot;http://dywicki.pl/court&quot; elementFormDefault=&quot;qualified&quot;&gt;
    &lt;annotation&gt;
        &lt;appinfo&gt;
            &lt;jaxb :globalBindings&gt;
                &lt;jaxb :javaType name=&quot;java.util.Calendar&quot; xmlType=&quot;date&quot;
                    parseMethod=&quot;javax.xml.bind.DatatypeConverter.parseDate&quot;
                    printMethod=&quot;javax.xml.bind.DatatypeConverter.printDate&quot; /&gt;
            &lt;/jaxb:globalBindings&gt;
        &lt;/appinfo&gt;
    &lt;/annotation&gt;

    &lt;!-- tutaj deklaracje typów --&gt;
&lt;/schema&gt;</pre>
<p>Podobne rozwiązanie można wykorzystać na poziomie pojedyńczego elementu aby zmapować konkretny element do obiektu. Element annotation można również dodać do deklaracji simpleType (powiedzmy reprezentacja numeru pesel + proste restrykcje).</p>
<pre class="brush: xml;">
    &lt;complextype name=&quot;File&quot;&gt;
        &lt;sequence&gt;
            &lt;element name=&quot;category&quot; type=&quot;string&quot;&gt;
                &lt;annotation&gt;
                    &lt;appinfo&gt;
                        &lt;jaxb :javaType
                            name=&quot;pl.dywicki.court.Category&quot;
                            parseMethod=&quot;pl.dywicki.court.Category.parse&quot;
                            printMethod=&quot;pl.dywicki.court.Category.print&quot;
                        /&gt;
                    &lt;/appinfo&gt;
                &lt;/annotation&gt;
            &lt;/element&gt;
        &lt;/sequence&gt;
    &lt;/complextype&gt;
</pre>
<p>JAXB wygeneruje wówczas odpowiednie adnotacje dla tworzonych klas oraz adaptery, które odwołują się do metod wskazanych w atrybutach elementu <b>javaType</b>.</p>
<p>W moim przypadku kod klasy Category wygląda następująco:</p>
<pre class="brush: java;">package pl.dywicki.court;

/**
 * Reprezentacja kategorii sprawy.
 *
 * @author Lukasz Dywicki &lt;a href=&quot;mailto:luke@code-house.net&quot;&gt;luke@code-house.net&lt;/a&gt;
 **/
public class Category {

    private String name;

    public Category(String value) {
        this.name = value;
    }

    public static Category parse(String value) {
        return new Category(value);
    }

    public static String print(Category value) {
        return value.name;
    }
}</pre>
<p>Jest to oczywiście maksymalnie uproszczony przykład. W konstruktorze bądź metodach, które konwertują string do obiektu możemy podpiąć walidację i bronić się wyjątkami przed nieprawidłowymi wartościami by uniemożliwić deserializację dokumentu.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2008/05/17/jaxb-2-zabawy-z-data-i-konwersja-typow/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Rozszerzanie JAXB</title>
		<link>http://blog.dywicki.pl/2007/11/28/rozszezanie-jaxb/</link>
		<comments>http://blog.dywicki.pl/2007/11/28/rozszezanie-jaxb/#comments</comments>
		<pubDate>Wed, 28 Nov 2007 14:12:33 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JAXB]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=200</guid>
		<description><![CDATA[Z ostatnich not zebrało mi się kilka obietnic. Jedną z nich było omówienie pluginów w wydaniu JAXB. Jako, że dzisiaj urządziłem sobie wolny dzień postanowiłem wywiązać się przynajmniej z części obowiązków z tym i z tych blogowych. Przykład, na którym do tej pory zawsze bazowałem to dodanie wsparcia dla obsługi zdarzeń z użyciem PropertyChangeSupport. Jest [...]]]></description>
			<content:encoded><![CDATA[<p>Z ostatnich not zebrało mi się kilka obietnic. Jedną z nich było omówienie pluginów w wydaniu JAXB. Jako, że dzisiaj urządziłem sobie wolny dzień postanowiłem wywiązać się przynajmniej z części obowiązków z tym i z tych blogowych.<br />
<span id="more-200"></span><br />
Przykład, na którym do tej pory zawsze bazowałem to dodanie wsparcia dla obsługi zdarzeń z użyciem PropertyChangeSupport. Jest to przykład o tyle wygodny, że pojawiają się przy nim nowe pole, przynajmniej dwie nowe metody. W grę wchodzi również wybiórcza modyfikacja metod, które zadeklarował sobie już JAXB. Z drugiej strony przykład ten jest o tyle niezręczny, że jest to już fragment <a href="https://jaxb2-commons.dev.java.net/">jaxb-commons</a>. Jakkolwiek ciężko mi wymyślić coś bardziej kreatywnego co by odnosiło się do ogółu generowanego kodu.</p>
<p>Mamy już pomysł, teraz zatem kolej na kod. Pluginy są podpinane przez XJC i są odpalane po procesie parsowania schematu <acronym title="eXtensible Markup Language">XML</acronym>.<br />
Krok po kroku co należy zrobić.</p>
<ul>
<li>Stworzyć klasę rozszerzającą <b>com.sun.tools.xjc.Plugin</b></li>
<li>Stworzyć jar, który będzie zawierał plugin (chociażby skryptem ant). Poniższy przykład pakuje wszystko z bin_plugin oraz katalog META-INF.</li>
</ul>
<pre class="brush: xml;">&lt;project name=&quot;plugin&quot; default=&quot;jar&quot;&gt;
	&lt;target name=&quot;jar&quot;&gt;
		&lt;delete file=&quot;plugin.jar&quot; /&gt;
		&lt;jar destfile=&quot;plugin.jar&quot;&gt;
			&lt;fileset dir=&quot;bin_plugin&quot; /&gt;
			&lt;fileset file=&quot;./*&quot; excludes=&quot;*&quot; includes=&quot;META-INF/**&quot; /&gt;
		&lt;/jar&gt;
	&lt;/target&gt;
&lt;/project&gt;</pre>
<ul>
<li>W paczce (jar) należy należy stworzyć plik <b>META-INF/services/com.sun.tools.xjc.Plugin</b></li>
<li>W pliku tym należy umieścić listę kolejnych pluginów - to znaczy wymienić pełne nazwy klas, po kolei każdą w nowej linii
</li>
</ul>
<pre class="brush: java;">com.sun.tools.xjc.addon.locator.SourceLocationAddOn
com.sun.tools.xjc.addon.sync.SynchronizedMethodAddOn
com.sun.tools.xjc.addon.at_generated.PluginImpl
pl.dywicki.plugin.PropertyChangePlugin</pre>
<p>Mając tak przygotowane archiwum uruchamiamy xjc:</p>
<pre class="brush: plain;">xjc -cp nasz.jar -extension -nasz_plugin schemat.xsd</pre>
<p>Kilka słów wyjaśnienia -cp to class path, -extension włącza pluginy, a -nasz_plugin informuje xjc, że chcemy uruchomić plugin, który legitymuje się taką dyrektywą.</p>
<p>Po tych wszystkich karkołomnych zabiegach możemy spokojnie zabrać się za kodowanie..</p>
<pre class="brush: java;">package pl.dywicki.plugin;

import java.beans.PropertyChangeSupport;

import javax.xml.bind.annotation.XmlTransient;

import org.xml.sax.ErrorHandler;

import com.sun.codemodel.JBlock;
import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JExpr;
import com.sun.codemodel.JFieldRef;
import com.sun.codemodel.JFieldVar;
import com.sun.codemodel.JInvocation;
import com.sun.codemodel.JMethod;
import com.sun.codemodel.JMod;
import com.sun.codemodel.JVar;
import com.sun.tools.xjc.Options;
import com.sun.tools.xjc.Plugin;
import com.sun.tools.xjc.outline.ClassOutline;
import com.sun.tools.xjc.outline.Outline;

/**
 * Plugin dorzucający do wygenerowanych klas obsługę powiadamiania o zmianach
 *
 * @author Łukasz Dywicki
 */
public class PropertyChangePlugin extends Plugin {

	@Override
	public String getOptionName() {
		// nasz plugin będzie uruchomiony poprzez dyrektywę -Xlistener
		return &quot;Xlistener&quot;;
	}

	@Override
	public String getUsage() {
		// help dla użytkownika
		return &quot;  -Xlistener propagowanie zdarzeń przy pomocy standardów JavaBeans&quot;;
	}

	@Override
	public boolean run(Outline outline, Options opt, ErrorHandler errorHandler) {
		// a to jest najważniejsza część pluginu :)

		// przeglądamy wszystkie dostępne klasy
		for (ClassOutline co : outline.getClasses()) {
			// definicja pojedyńczej klasy, przy pomocy JDefinedClass
			// możemy dodawać nowe własności etc
			JDefinedClass clazz = co.implClass;

			addField(clazz);

			changeMethods(clazz);
		}
		return true;
	}

	/**
	 * Dodanie pola do generowanej klasy.
	 *
	 * @param clazz Klasa do której dorzucamy pole
	 */
	private void addField(JDefinedClass clazz) {
		// tworzymy w wygenerowanej klasie pole
		// private PropertyChangeSupport support = new PropertyChangeSupport(this);
		JFieldVar $field = clazz.field(JMod.PRIVATE | JMod.TRANSIENT, PropertyChangeSupport.class, &quot;support&quot;);
		// inicjujemy pole
		JInvocation _new = JExpr._new($field.type());
		// dodajemy argument (this)
		_new.arg(JExpr._this());
		$field.init(_new);
		// dodanie adnotacji @XmlTransient do pola, aby nie było ono
		// obsługiwane przez JAXB
		$field.annotate(XmlTransient.class);
	}

	/**
	 * Modyfikacja metod set*..
	 *
	 * @param clazz Klasa którą &quot;przerabiamy&quot;.
	 **/
	private void changeMethods(JDefinedClass clazz) {
		for (JMethod method : clazz.methods()) {
			if (method.name().startsWith(&quot;set&quot;)) {
				String tmp = method.name().substring(3);
				String fieldName = tmp.substring(0, 1).toLowerCase()
					+ tmp.substring(1);
				addSupport(method, fieldName);
			}
		}
	}

	/**
	 * Zmodyfikowanie istniejących metod.
	 *
	 * @param method Obiekt metody
	 * @param fieldName Nazwa pola, które metoda obsługuje
	 */
	private void addSupport(JMethod method, String fieldName) {
		// przeskakujemy do pierwszej linijki w metodzie
		JBlock body = method.body();
		body.pos(0);
		// odwoładnie do np this.userName
		JFieldRef ref = JExpr.ref(fieldName);
		// deklaracja zmiennej o typie pierwszego argumentu i nazwie temp
		JVar $temp = body.decl(method.listParams()[0].type(), &quot;temp&quot;);
		// przypisanie do zmiennej temp wartości pola
		$temp.init(JExpr.ref(fieldName));

		// przeskoczenie na koniec metody
		body.pos(body.getContents().size());

		// odwołanie do pola this.support (stworzone w metodzie addField) i
		// wywołanie metody this.support.firePropertyChange()
		JInvocation invocation = JExpr.ref(&quot;support&quot;).invoke(&quot;firePropertyChange&quot;);
		// kolejne argumenty metody - nazwa property, stara wartość i nowa wartość
		invocation.arg(fieldName);
		invocation.arg($temp);
		invocation.arg(ref);

		// dorzucenie wywołania na końcu metody
		body.add(invocation);
	}

}</pre>
<p>Kosztuje to troszkę pracy, ale koniec końców mamy wsparcie dla obsługi zdarzeń. Dla zainteresowanych dołączam jeszcze dwa pluginy - generujące metody <a href="http://media.dywicki.pl/blog/jaxb/HashCodePlugin.java">hashCode</a> i <a href="http://media.dywicki.pl/blog/jaxb/EqualsPlugin.java">equals</a>. Napisałem je, gdy nie miałem dostępu do internetu, jeśli chcecie ich używać - zalecam wcześniej wspomniane jaxb-commons.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2007/11/28/rozszezanie-jaxb/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>WarsJava</title>
		<link>http://blog.dywicki.pl/2007/11/20/warsjava/</link>
		<comments>http://blog.dywicki.pl/2007/11/20/warsjava/#comments</comments>
		<pubDate>Mon, 19 Nov 2007 23:16:47 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JAXB]]></category>
		<category><![CDATA[Wiadomości]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=199</guid>
		<description><![CDATA[W sobotę 17 listopada odbyła się WarsJava. Seria warsztatów realizowana przez Warszawski JUG, a dokładniej przez dwie osoby (kolejność losowa) Jacka Laskowskiego i Łukasza Świerczyńskiego. Program prezentacji zapowiadał się i był ciekawy. Przede wszystkim rzecz z którą wiązałem największe zainteresowanie to tandem Spring+OSGi, głównie z racji na podpinanie Springa pod Eclipse RCP. Drugi temat, który [...]]]></description>
			<content:encoded><![CDATA[<p>W sobotę 17 listopada odbyła się <a href="http://warsjava.pl">WarsJava</a>. Seria warsztatów realizowana przez <a href="http://groups.google.com/group/warszawa-jug">Warszawski JUG</a>, a dokładniej przez dwie osoby (kolejność losowa) Jacka Laskowskiego i Łukasza Świerczyńskiego.<br />
<span id="more-199"></span><br />
Program prezentacji zapowiadał się i był ciekawy. Przede wszystkim rzecz z którą wiązałem największe zainteresowanie to tandem Spring+OSGi, głównie z racji na podpinanie Springa pod Eclipse RCP. Drugi temat, który był mi bliski to Spring Web MVC + Freemaker, z racji na to, że z jednym i drugim będę miał prawdopodobnie styczność w pracy.<br />
 Trzeci tematem, który budził z mojej strony stosunkowo niskie zainteresowanie było JRuby, jednak sama treść prezentacji i sposób jej prowadzenia spowodowały że wciąż jestem pod wrażeniem tego mariażu Javy i Ruby. Wiktorowi podczas prezentacji wyskoczył tylko jeden chochlik, którego dosyć sprawnie wyeliminował. :)</p>
<p>Na końcu chciałem wspomnieć o tym że i ja miałem swój udział na WarsJavie prowadząc warsztat na temat JAXB. Prawdę powiedziawszy czułem się nieco przerażony - wszyscy podjęli się poważnych tematów, Spring, OSGi, JRuby, JMS podczas gdy ja miałem powiedzieć o bibliotece do robienia obiektów z XMLa i XMLa z obiektów. Szczerze powiedziawszy miałem również spore obawy czy treść, którą przygotowałem będzie w stanie zapełnić półtorej godziny, jakie dostałem na prezentację tematu. Postanowiłem więc dokładnie napisać co jest do zrobienia, dopieścić przykłady, wynikiem czego kładłem się spać o 3 w nocy. Węsząc problemy zawczasu spakowałem laptopa, jak się okazało słusznie - obudziłem się na tyle prędko, że zdążyłem wciągnąć spodnie, wybiec na tramwaj.. Gdy dotarłem na miejsce była już 9:10, dosłownie pięć minut przed rozpoczęciem. Byłaby niezła wpadka gdyby zwiał mi tramwaj i musiałbym czekać 10 minut na kolejny. Szczęście - udało się dotrzeć. Na początku drobne problemy z rzutnikiem, następnie z konfiguracją rozdzielczości.. i tym sposobem uleciało dobre 15 minut.<br />
Parę slajdów, które miałem przygotowane minęło stanowczo zbyt szybko i musiałem siadać do klawiatury. Dziwna rzecz, kiedy człowiek siada, używa tylko dłoni, a mimo wszystko język ma zaplątany. :) Zaiste, problematyczne było pisanie i mówienie. Właściwie to więcej pisałem jak mówiłem. Czas zleciał bardzo szybko, zdążyłem w zasadzie omówić 2 aspekty, na które się gotowałem czyli użycie adnotacji i generowanie kodu ze schematu XSD jak i jeden na który się nie przygotowywałem - radzenie sobie z wyjątkami ;). Nie zdążyłem nic powiedzieć na temat wpływania na zachowanie kompilatora schemy (xjc) poprzez tworzenie plików xjb oraz pisania własnych pluginów. Te punkty staną się najprawdopodobniej tematem przyszłych not.<br />
Szczerze byłem również bardzo mile zaskoczony tym, że ktoś poprosił o kod po prezentacji. :)</p>
<p>Na grupie pojawił się <a href="http://groups.google.com/group/warszawa-jug/t/86c5848c35abd7b">wątek z opiniami</a> po warsztatach. Niestety nie byłem na <a href="http://javarsovia.pl">Javarsovii</a> i nie mam punktu odniesienia "co było lepsze". Jakkolwiek zdaje mi się, że tradycyjne prezentacje, gdzie jest kilkanaście slajdów i odrobina kodu zdaje się lepsze. Daje dosyć ogólny pogląd na więcej aspektów niż powstający kod. Z drugiej jednak strony forma warsztatu jest bardziej efektowna, co można było bez wątpienia zaobserwować w przypadku JRuby. Z resztą sama dyskusja tuż po prezentacji Wiktora mogła pokazać jak wiele emocji budzi owe novum. :)</p>
<p>Dla zainteresowanych - zamieściłem <a href="http://media.dywicki.pl/blog/warsjava/jaxb-code.zip">źródła wszystkich projektów</a> jakie realizowałem przed i w trakcie prezentacji oraz <a href="http://media.dywicki.pl/blog/warsjava/jaxb-avi.zip">filmik</a> "z kodowania" (nagrany w <a href="http://camstudio.org/">Cam Studio</a>). Ostrzegam, że avik jest słabo skompresowany i <b>po wypakowaniu zajmuje 670MB</b>!</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2007/11/20/warsjava/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Weź do Javy to co chcesz z PHP!</title>
		<link>http://blog.dywicki.pl/2007/11/09/wez-do-javy-to-co-chcesz-z-php/</link>
		<comments>http://blog.dywicki.pl/2007/11/09/wez-do-javy-to-co-chcesz-z-php/#comments</comments>
		<pubDate>Thu, 08 Nov 2007 23:52:05 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JAXB]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=197</guid>
		<description><![CDATA[Integracja między językami czy też platformami to kwestia poruszana nie od dzisiaj. Na poziomie platform funkcjonuje od dłuższego czasu CORBA i Web Services z trio SOAP + WSDL + XML Schema na czele. Integracja systemów napisanych w tym samym języku sprowadza się zwykle do wykorzystania serializacji, która jest najszybsza i najwygodniejsza. Gorzej jeśli idzie o [...]]]></description>
			<content:encoded><![CDATA[<p>Integracja między językami czy też platformami to kwestia poruszana nie od dzisiaj. Na poziomie platform funkcjonuje od dłuższego czasu CORBA i Web Services z trio <acronym title="Simple Object Access Protocol">SOAP</acronym> + <acronym title="Web Services Description Language">WSDL</acronym> + <acronym title="eXtensible Markup Language">XML</acronym> Schema na czele. Integracja systemów napisanych w tym samym języku sprowadza się zwykle do wykorzystania serializacji, która jest najszybsza i najwygodniejsza. Gorzej jeśli idzie o połączenie dwóch języków - w moim przypadku <acronym title="Pre-Hypertext Processing">PHP</acronym> i Javy.<br />
Zend ma swój mostek, który umożliwia na zintegrowanie Javy i <acronym title="Pre-Hypertext Processing">PHP</acronym>, jest też dodatkowe rozszerzenie do <acronym title="Pre-Hypertext Processing">PHP</acronym>, które pozwala na wykorzystanie Javy w <acronym title="Pre-Hypertext Processing">PHP</acronym>, jednakże moje oczekiwania nie był aż tak wielkie. Potrzebowałem po prostu odczytać dane specyficzne dla <acronym title="Pre-Hypertext Processing">PHP</acronym> - powiedzmy informacje o jakiejś klasie. Standardowo taka operacja wymagała stworzenia parsera, co jest zadaniem powiedzmy, nie na moje siły i umiejętności.. stąd też postanowiłem sobie nieco uprościć pracę. :)<br />
<span id="more-197"></span><br />
Wspólny, najwygodniejszy format (zarówno w odczycie i zapisie danych) z jednej i drugiej strony to oczywiście <acronym title="eXtensible Markup Language">XML</acronym>. Problem w tym, jaki format ma być wykorzystany. Nie da się przecież bezpośrednio odwzorować obiektu z <acronym title="Pre-Hypertext Processing">PHP</acronym> do Javy głównie z racji na dynamikę. Jeśli w <acronym title="Pre-Hypertext Processing">PHP</acronym> ktoś dorzuci pole do obiektu, poprzez proste <b>$someUser->city = 'Białystok'</b> to Java bazująca tylko na statycznych, zadeklarowanych polach w klasie nie odczyta tej informacji. Serializacja w postaci specyficznej dla <acronym title="Pre-Hypertext Processing">PHP</acronym> również wiąże się ze stworzeniem parsera po stronie Javy by to wszystko obsługiwać i dodatkowo coś co by później mapowało obiekty z Javy do XMLa w postaci przyjaznej dla <acronym title="Pre-Hypertext Processing">PHP</acronym>. Wyjściem z całej sytuacji okazały się funkcje <a href="http://pl2.php.net/manual/en/ref.wddx.php">wddx_*</a>. Po prostu strzał w dziesiątkę. <a href="http://www.openwddx.org/">WDDX</a> to standard może nie najnowszy, ale dosyć spójny, i co najważniejsze umożliwiający przesyłanie złożonych obiektów bez zbytniej walki. Po chwili poszukiwań znalazłem <a href="http://www.openwddx.org/downloads/dtd/wddx_dtd_10.txt"><acronym title="Document Type Definition">DTD</acronym></a>, zatem ze strony Javy wystarczy odpalić <a href="http://java.sun.com/webservices/jaxb/index.jsp">JAXB</a> i jesteśmy na miejscu.</p>
<p>Przykładowy skrypt <acronym title="Pre-Hypertext Processing">PHP</acronym>, który uzyskuje informacje o konfiguracji Agavi:</p>
<div class="igBar"><span id="lphp-6"><a href="#" onclick="javascript:showPlainTxt('php-6'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">PHP:</span>
<div id="php-6">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&amp;lt;?php</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#007700;">include_once</span> <span style="color:#DD0000;">'E:/htdocs/shop/agavi/agavi.php'</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000BB;">$value</span> = <span style="color:#3A6A8B;">wddx_serialize_value</span><span style="color:#0000BB; font-style: bold;">&#40;</span>AgaviConfig::<span style="color:#3A6A8B;">export</span><span style="color:#0000BB; font-style: bold;">&#40;</span><span style="color:#0000BB; font-style: bold;">&#41;</span><span style="color:#0000BB; font-style: bold;">&#41;</span>;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000BB;">$value</span> = &amp;quot;&amp;lt;?xml version=<span style="color:#DD0000;">'1.0'</span> encoding=<span style="color:#DD0000;">'utf-8'</span> ?&amp;gt;\n&amp;lt;!DOCTYPE wddxPacket <span style="color:#3A6A8B;">SYSTEM</span> <span style="color:#DD0000;">'wddx.dtd'</span>&amp;gt;\n&amp;quot; . <span style="color:#0000BB;">$value</span>;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#007700;">echo</span> <span style="color:#0000BB;">$value</span>; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>A teraz część wyniku, który <acronym title="Pre-Hypertext Processing">PHP</acronym> wyświetla w konsoli:</p>
<div class="igBar"><span id="lxml-7"><a href="#" onclick="javascript:showPlainTxt('xml-7'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">XML:</span>
<div id="xml-7">
<div class="xml">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #ddbb00;">&amp;lt;</span>?xml version=<span style="color: #ddbb00;">&amp;quot;</span>1.0<span style="color: #ddbb00;">&amp;quot;</span> encoding=<span style="color: #ddbb00;">&amp;quot;</span>utf-8<span style="color: #ddbb00;">&amp;quot;</span> ?<span style="color: #ddbb00;">&amp;gt;</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #ddbb00;">&amp;lt;</span>!DOCTYPE wddxPacket SYSTEM 'wddx.dtd'<span style="color: #ddbb00;">&amp;gt;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #ddbb00;">&amp;lt;</span>wddxpacket version='1.0'<span style="color: #ddbb00;">&amp;gt;</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #ddbb00;">&amp;lt;</span>header /<span style="color: #ddbb00;">&amp;gt;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #ddbb00;">&amp;lt;</span>data<span style="color: #ddbb00;">&amp;gt;</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ddbb00;">&amp;lt;</span>struct<span style="color: #ddbb00;">&amp;gt;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ddbb00;">&amp;lt;</span>var name='core.minimum_php_version'<span style="color: #ddbb00;">&amp;gt;</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ddbb00;">&amp;lt;</span>string<span style="color: #ddbb00;">&amp;gt;</span>5.1.0<span style="color: #ddbb00;">&amp;lt;</span>/string<span style="color: #ddbb00;">&amp;gt;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ddbb00;">&amp;lt;</span>/var<span style="color: #ddbb00;">&amp;gt;</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ddbb00;">&amp;lt;</span>var name='core.agavi_dir'<span style="color: #ddbb00;">&amp;gt;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ddbb00;">&amp;lt;</span>string<span style="color: #ddbb00;">&amp;gt;</span>E:\htdocs\shop\agavi<span style="color: #ddbb00;">&amp;lt;</span>/string<span style="color: #ddbb00;">&amp;gt;</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ddbb00;">&amp;lt;</span>/var<span style="color: #ddbb00;">&amp;gt;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ddbb00;">&amp;lt;</span>!-- i tak dalej --<span style="color: #ddbb00;">&amp;gt;</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ddbb00;">&amp;lt;</span>/struct<span style="color: #ddbb00;">&amp;gt;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color: #ddbb00;">&amp;lt;</span>/data<span style="color: #ddbb00;">&amp;gt;</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #ddbb00;">&amp;lt;</span>/wddxpacket<span style="color: #ddbb00;">&amp;gt;</span> </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Teraz kod Javy, który odczytuje sobie informacje.. (nawiasy kwadratowe przy listach podyktowane błędami w skrypcie, który koloruje składnię)</p>
<pre class="brush: java;">

		// odpalamy interpreter <acronym title="Pre-Hypertext Processing">PHP</acronym>
		Runtime runtime = Runtime.getRuntime();
		Process exec = runtime.exec(&quot;php -q E:/agavi-ide/org.codehouse.bridge/src/org/codehouse/bridge/test2.php&quot;);

		// podnosimy kontekst JAXB
		JAXBContext context = JAXBContext.newInstance(ObjectFactory.class);
		// deserializujemy <acronym title="eXtensible Markup Language">XML</acronym> wygenerowany przez <acronym title="Pre-Hypertext Processing">PHP</acronym>
		WddxPacket object = (WddxPacket) context.createUnmarshaller().unmarshal(exec.getInputStream());

		// odczytujemy informacje
		for (Object stc : object.getData().getWDDXData()) {
			// spodziewamy się informacji o typie złożonym
			if (stc instanceof Struct) {
				List[generated.Var] vara = ((Struct) stc).getVar();
				for (Var value : vara) {
					// pozostaje nam tylko odczytanie zserializowanej wartości
					List[Object] configurationValue = value.getWDDXData();
					System.out.println(value.getName() + &quot;: &quot; + ((generated.String) configurationValue.get(0)).getvalue());
				}
			}
		}
</pre>
<p>Wynik działania poniższego kodu to:</p>
<div class="igBar"><span id="lcode-8"><a href="#" onclick="javascript:showPlainTxt('code-8'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-8">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">core.<span style="">minimum_php_version</span>: <span style="color:#800000;color:#800000;">5</span>.<span style="color:#800000;color:#800000;">1</span>.<span style="color:#800000;color:#800000;">0</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">core.<span style="">agavi_dir</span>: E:\htdocs\shop\agavi</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">exception.<span style="">default_template</span>: E:\htdocs\shop\agavi/exception/templates/shiny.<span style="">php</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">agavi.<span style="">name</span>: Agavi</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">agavi.<span style="">major_version</span>: <span style="color:#800000;color:#800000;">0</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">agavi.<span style="">minor_version</span>: <span style="color:#800000;color:#800000;">11</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">agavi.<span style="">micro_version</span>: <span style="color:#800000;color:#800000;">0</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">agavi.<span style="">status</span>: DEV</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">agavi.<span style="">branch</span>: trunk</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">agavi.<span style="">version</span>: <span style="color:#800000;color:#800000;">0</span>.<span style="color:#800000;color:#800000;">11</span>.<span style="color:#800000;color:#800000;">0</span>-DEV</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">agavi.<span style="">release</span>: Agavi <span style="color:#800000;color:#800000;">0</span>.<span style="color:#800000;color:#800000;">11</span>.<span style="color:#800000;color:#800000;">0</span>-DEV</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">agavi.<span style="">url</span>: http:<span style="color:#FF9933; font-style:italic;">//www.agavi.org</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">agavi_info: Agavi <span style="color:#800000;color:#800000;">0</span>.<span style="color:#800000;color:#800000;">11</span>.<span style="color:#800000;color:#800000;">0</span>-DEV <span style="color:#006600; font-weight:bold;">&#40;</span>http:<span style="color:#FF9933; font-style:italic;">//www.agavi.org) </span></div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Czyli wszystko czego trzeba było nam do szczęścia! :)</p>
<p>Pora na przykład bardziej złożony, wyciągnięcie informacji o jakiejś klasie widoku użytej w aplikacji opartej o Agavi.</p>
<div class="igBar"><span id="lphp-9"><a href="#" onclick="javascript:showPlainTxt('php-9'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">PHP:</span>
<div id="php-9">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&amp;lt;?php</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#007700;">include_once</span> <span style="color:#DD0000;">'E:/htdocs/shop/agavi/agavi.php'</span>;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">AgaviConfig::<span style="color:#3A6A8B;">set</span><span style="color:#0000BB; font-style: bold;">&#40;</span><span style="color:#DD0000;">'core.app_dir'</span>, <span style="color:#DD0000;">'E:/htdocs/shop/project/'</span><span style="color:#0000BB; font-style: bold;">&#41;</span>;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">AgaviConfig::<span style="color:#3A6A8B;">set</span><span style="color:#0000BB; font-style: bold;">&#40;</span><span style="color:#DD0000;">'core.system_config_dir'</span>, <span style="color:#DD0000;">'E:/htdocs/shop/agavi/config/defaults/'</span><span style="color:#0000BB; font-style: bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF8000; font-style:italic;">// metoda dopisana przeze mnie, konfiguruje Agavi bez wyrzucania wyjątków.</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Agavi::<span style="color:#3A6A8B;">bootstrap2</span><span style="color:#0000BB; font-style: bold;">&#40;</span><span style="color:#DD0000;">''</span><span style="color:#0000BB; font-style: bold;">&#41;</span>;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#007700;">include_once</span> <span style="color:#DD0000;">'E:/htdocs/shop/project/modules/Cart/lib/BaseInputView.class.php'</span>;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000BB;">$obj</span> = <span style="color:#007700; font-weight:bold;">new</span> ReflectionClass<span style="color:#0000BB; font-style: bold;">&#40;</span><span style="color:#DD0000;">'Cart_BaseInputView'</span><span style="color:#0000BB; font-style: bold;">&#41;</span>;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000BB;">$orig</span> = <span style="color:#0000BB;">$obj</span>-&amp;gt;getFileName<span style="color:#0000BB; font-style: bold;">&#40;</span><span style="color:#0000BB; font-style: bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000BB;">$myMethods</span> = <span style="color:#0000BB;">$obj</span>-&amp;gt;getMethods<span style="color:#0000BB; font-style: bold;">&#40;</span><span style="color:#0000BB; font-style: bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000BB;">$methods</span> = <span style="color:#3A6A8B;">array</span><span style="color:#0000BB; font-style: bold;">&#40;</span><span style="color:#0000BB; font-style: bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#007700;">foreach</span> <span style="color:#0000BB; font-style: bold;">&#40;</span><span style="color:#0000BB;">$myMethods</span> <span style="color:#007700;">as</span> <span style="color:#0000BB;">$method</span><span style="color:#0000BB; font-style: bold;">&#41;</span> <span style="color:#0000BB; font-style: bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#FF8000; font-style:italic;">// sprawdzenie czy plik w którym jest zadeklarowana metoda</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#FF8000; font-style:italic;">// pokrywa się z plikiem w którym jest zadeklarowana klasa</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#FF8000; font-style:italic;">// w ten sposób pozbywam się niepotrzebnych metod z klas nadrzędnych</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#007700;">if</span> <span style="color:#0000BB; font-style: bold;">&#40;</span><span style="color:#0000BB;">$method</span>-&amp;gt;getFileName<span style="color:#0000BB; font-style: bold;">&#40;</span><span style="color:#0000BB; font-style: bold;">&#41;</span> == <span style="color:#0000BB;">$orig</span><span style="color:#0000BB; font-style: bold;">&#41;</span> <span style="color:#0000BB; font-style: bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000BB;">$methods</span><span style="color:#0000BB; font-style: bold;">&#91;</span><span style="color:#0000BB; font-style: bold;">&#93;</span> = <span style="color:#0000BB;">$method</span>;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000BB; font-style: bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000BB; font-style: bold;">&#125;</span></div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000BB;">$value</span> = <span style="color:#3A6A8B;">wddx_serialize_value</span><span style="color:#0000BB; font-style: bold;">&#40;</span><span style="color:#0000BB;">$methods</span><span style="color:#0000BB; font-style: bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000BB;">$value</span> = &amp;quot;&amp;lt;?xml version=<span style="color:#DD0000;">'1.0'</span> encoding=<span style="color:#DD0000;">'utf-8'</span> ?&amp;gt;&amp;lt;!DOCTYPE wddxPacket <span style="color:#3A6A8B;">SYSTEM</span> <span style="color:#DD0000;">'wddx.dtd'</span>&amp;gt;\n&amp;quot; . <span style="color:#0000BB;">$value</span>;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#007700;">echo</span> <span style="color:#0000BB;">$value</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">?&amp;gt; </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Drobna przeróbka kodu Javy, który był użyty wcześniej i wynikiem jest</p>
<div class="igBar"><span id="lcode-10"><a href="#" onclick="javascript:showPlainTxt('code-10'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">CODE:</span>
<div id="code-10">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">php_class_name: ReflectionMethod</div>
</li>
<li style="font-weight: normal;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">name: execute</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">class: Cart_BaseInputView </div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>Tym, którzy dobrnęli do końca tej noty dziękuję za wytrwałość. :) Kolejna nota będzie być może o tym jak wywoływać metody statyczne klas Javy z poziomu <acronym title="eXtensible Stylesheet Language Transformations">XSLT</acronym> (wierzcie mi, da się!).</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2007/11/09/wez-do-javy-to-co-chcesz-z-php/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Mój pierwszy edytor&#8230;</title>
		<link>http://blog.dywicki.pl/2007/11/07/moj-pierwszy-edytor/</link>
		<comments>http://blog.dywicki.pl/2007/11/07/moj-pierwszy-edytor/#comments</comments>
		<pubDate>Tue, 06 Nov 2007 22:44:39 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Agavi]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JAXB]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SWT]]></category>
		<category><![CDATA[Wiadomości]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=196</guid>
		<description><![CDATA[Czas jakiś temu udało mi się stworzyć pierwszy działający edytor w oparciu o Eclipse. Kilka informacji co pod spodem: SharedHeaderFormEditor - ładny tekstowy nagłówek oraz możliwość dodawania zakładek FormPage i FormToolkit - użyte do stworzenia układu, który widać na załączonym obrazku JFace Databinding - zapewnia propagowanie zmian z formularza do obiektów JAXB 2 - mapowanie [...]]]></description>
			<content:encoded><![CDATA[<p><a href='http://blog.dywicki.pl/wp-content/uploads/2007/11/agavi-editor.JPG' title='Agavi module configuration editor' rel="lightbox"><img align="right" src='http://blog.dywicki.pl/wp-content/uploads/2007/11/agavi-editor.thumbnail.JPG' alt='Agavi module configuration editor'  rel="lightbox"/></a></p>
<p>Czas jakiś temu udało mi się stworzyć pierwszy działający edytor w oparciu o Eclipse.<br />
Kilka informacji co pod spodem:</p>
<ul>
<li>SharedHeaderFormEditor - ładny tekstowy nagłówek oraz możliwość dodawania zakładek</li>
<li>FormPage i FormToolkit - użyte do stworzenia układu, który widać na załączonym obrazku</li>
<li>JFace Databinding - zapewnia propagowanie zmian z formularza do obiektów</li>
<li>JAXB 2 - mapowanie plików <acronym title="eXtensible Markup Language">XML</acronym> do odpowiednich klas</li>
<li>JFace - table viewer i parę innych dodatków</li>
</ul>
<p>Całość ogólnie jest prosta niczym konstrukcja cepa, w działaniu sprawia się dobrze. Jak tylko ogarnę kod postaram się opisać krok po kroku jak można coś podobnego stworzyć na własny użytek. </p>
<p>Splatch wraca do gry i będzie grać wysoko! ;-)</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2007/11/07/moj-pierwszy-edytor/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>JAXB 2, Wprowadzenie</title>
		<link>http://blog.dywicki.pl/2007/10/14/jaxb-2-wprowadzenie/</link>
		<comments>http://blog.dywicki.pl/2007/10/14/jaxb-2-wprowadzenie/#comments</comments>
		<pubDate>Sun, 14 Oct 2007 17:29:57 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JAXB]]></category>
		<category><![CDATA[tlumaczenia]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=190</guid>
		<description><![CDATA[W ramach WarsJava, konferencji/warsztatów organizowanych przez Warszawski JUG, będę miał szansę przedstawić publiczności Java Architecture for XML Binding w wersji drugiej. Swoje boje z JAXB postanowiłem opisać na blogu, być może dla kogoś temat wyda się interesujący.. :) Ogólniki JAXB ma za zadanie ułatwić pracę z XML poprzez automatyczne dostarczanie obiektów zamiast żmudnego, ręcznego obrabiania [...]]]></description>
			<content:encoded><![CDATA[<p>W ramach <a href="http://groups.google.com/group/warszawa-jug/web/warsjava">WarsJava</a>, konferencji/warsztatów organizowanych przez <a href="http://warszawa.jug.pl/">Warszawski JUG</a>, będę miał szansę przedstawić publiczności <a href="https://jaxb.dev.java.net/">Java Architecture for <acronym title="eXtensible Markup Language">XML</acronym> Binding</a> w wersji drugiej. Swoje boje z JAXB postanowiłem opisać na blogu, być może dla kogoś temat wyda się interesujący.. :)<br />
<span id="more-190"></span></p>
<h2>Ogólniki</h2>
<p>JAXB ma za zadanie ułatwić pracę z <acronym title="eXtensible Markup Language">XML</acronym> poprzez automatyczne dostarczanie obiektów zamiast żmudnego, ręcznego obrabiania plików SAX, <acronym title="Document Object Model">DOM</acronym> czy StAX. Jest to dodatkowa warstwa zbudowana na bazie <a href="http://java.sun.com/webservices/jaxp/index.jsp">Java Api for <acronym title="eXtensible Markup Language">XML</acronym> Processing<br />
</a>. Druga wersja JAXB jest dołączona do J2SE 1.6.</p>
<p>Spójrzmy teraz na schemat budowy JAXB:<br />
<img src="http://blog.dywicki.pl/wp-content/uploads/2007/10/jaxb-overview.gif" alt="JAXB, schemat" style="margin: 5px" /></p>
<ol>
<li> Kompilator
<ol>
<li><b>Schema</b> - dokument opisujący strukturę dokumentu - może to być <acronym title="eXtensible Markup Language">XML</acronym> Schema, <acronym title="Document Type Definition">DTD</acronym> jak również Relax NG czy też <acronym title="Web Services Description Language">WSDL</acronym>.
        </li>
<li><b><acronym title="eXtensible Markup Language">XML</acronym> /Java Binding Customization</b> - JAXB daje nam możliwość wpływania na wygenerowany kod poprzez ten właśnie mechanizm, dzięki temu można określić np. metody, które będą tworzyć elementy w przypadku odczytu z dokumentu bądź serializować w przypadku zapisu.</li>
</ol>
</li>
<li> Runtime
<ol>
<li><b>Portable JAXB-annotated classes</b> - kod, który wygenerowaliśmy przy użyciu kompilatora bądź klasy, do których dodaliśmy adnotacje.</li>
<li><b>Object Factory</b> - klasa, która tworzy obiektowe reprezentacje naszych elementów <acronym title="eXtensible Markup Language">XML</acronym>.</li>
<li><b>Binding runtime framework implementation</b> - obsługuje proces odczytu danych (<i>unmarshalling</i>) oraz ich zapisu (<i>marshalling</i>), obsługuje również walidację. Element ten do poprawnego działania wymaga elementów wymienionych powyżej - czyli klas z adnotacjami oraz ich "fabryki".</li>
</ol>
</li>
</ol>
<h2>Pierwszy projekt</h2>
<p>Pamiętam, że kiedyś chciałem stworzyć prostą aplikację w której mógłbym notować jakie książki mam i komu je wypożyczyłem. Niestety w którymś momencie zabrakło chyba sił i poza definicją struktury dokumentu stworzyłem tyko kilka linii kodu. Nie mniej, po drobnych przeróbkach udało się doprowadzić schemat do porządku. W aplikacji będą występować następujące instancje klas:</p>
<ol>
<li><b>Books</b> - repozytorium książek, zawiera listę książek</li>
<li><b>Book</b> - definicja książki - atrybuty to title, isbn oraz lista autorów</li>
<li><b>Author</b> - reprezentacja autora - atrybuty firstName, lastName. Dodatkowo opcjonalny jest type wskazujący czy mamy do czynienia z tłumaczem czy też z "normalnym" autorem.</li>
<li><b>AuthorType</b> - typ wyliczeniowy - dostępne wartości to Translator, Author</li>
</ol>
<p>Aby korzystało się nam z kompilatora (xjc) wygodniej podepniemy go pod Eclipse jako narzędzie zewnętrzne. Tu przyda się kilka informacji na temat samego kompilatora:<br />
xjc [-options ...] file/URL/dir ... [-b bindinfo] ...<br />
Gdzie najważniejsze opcje to:</p>
<ol>
<li><b>-d</b>, katalog do którego trafi wygenerowany kod</li>
<li><b>-b</b>, dodatkowe mappingi umożliwiające zmianę zachowania kompilatora</li>
<li><b>-p</b>, paczka do której trafi wygenerowany kod</li>
<li><b>-classpath</b>, miejsca w których xjc ma szukać klas, które zostały użyte w mappingach</li>
</ol>
<p>Przykładowo</p>
<pre class="brush: bash;">xjc -d generated schema.xsd</pre>
<p><a href="http://blog.dywicki.pl/wp-content/uploads/2007/10/jaxb-external.JPG" title="Konfiruracja external tools" rel="lightbox" style="text-decodarion: none"><img src="http://blog.dywicki.pl/wp-content/uploads/2007/10/jaxb-external.thumbnail.JPG" alt="Konfiruracja external tools" rel="lightbox" style="margin: 10px;" align="left"/></a><br />
Spowoduje, że klasy wylądują w katalogu generated. Nazwa paczki zostanie zaczerpnięta z atrybutu targetNamespace dokumentu zawartego w schemacie. Obok znajduje się screen z konfiguracją - z ważniejszych informacji - <b>Working directory ustawione na ${project_loc}</b> pozwala nam się nawigować po katalogach względem aktualnie zaznaczonego w nawigatorze projektu. <b>wartość w polu Arguments -d generated ${resource_loc} -verbose -extension -npa</b> oznacza, że wygenerowane klasy wylądują w katalogu "generated" (należy stworzyć taki source folder). Zmienna ${resource_loc} pozwala nam użyć aktualnie zaznaczonego pliku w nawigatorze. Dzięki takiej konfiguracji niezależnie od projektu i pliku jesteśmy w stanie wygenerować potrzebne nam klasy poprzez dwa kliknięcia - pierwsze w nawigatorze, drugie na ikonie external tools.</p>
<p>Schemat jest <a href="http://media.dywicki.pl/blog/jaxb/books.xsd">dostępny do ściągnięcia</a>, podobnie jak <a href="http://media.dywicki.pl/blog/jaxb/books.xml">przykładowy plik z danymi</a>. Proszę zwrócić uwagę na to jak jest zdefiniowany główny element dokumentu - poprzez zawarcie typu anonimowego. Jeśli zdefiniujemy oddzielnie element i typ to wówczas konieczne będzie ręczne dodanie adnotacji @XmlRootElement przy klasie Books. O tym <a href="http://weblogs.java.net/blog/kohsuke/archive/2006/03/why_does_jaxb_p.html">dlaczego JAXB się tak zachowuje</a> można wyczytać na jednym z Sun-owskich blogów.</p>
<pre class="brush: java;">package pl.dywicki.books.app;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

import pl.dywicki.books.Author;
import pl.dywicki.books.AuthorType;
import pl.dywicki.books.Book;
import pl.dywicki.books.Books;
import pl.dywicki.books.ObjectFactory;

/**
 * Testowa klasa pokazująca użycie JAXB do zapisywania danych.
 *
 * @author Łukasz Dywicki
 */
public class App {

	public static void main(String[] args) throws Exception {

		// repozytorium książek
		Books books = new Books();

		// przykładowa książka
		Book book = new Book();
		book.setTitle(&quot;Test title&quot;);
		book.setIsbn(&quot;111-111-111&quot;);

		// testowy autor
		Author author = new Author();
		author.setFirstName(&quot;Martin&quot;);
		author.setLastName(&quot;Fowler&quot;);
		book.getAuthor().add(author);

		// testowy tłumacz
		author = new Author();
		author.setFirstName(&quot;Łukasz&quot;);
		author.setLastName(&quot;Dywicki&quot;);
		author.setType(AuthorType.TRANSLATOR);
		book.getAuthor().add(author);

		// dodanie książki do repozytorium
		books.getBook().add(book);

		JAXBContext context = JAXBContext.newInstance(ObjectFactory.class);
		Marshaller marshaller = context.createMarshaller();
		// chcemy ładnych wcięć w wyniku! :)
		marshaller.setProperty(&quot;jaxb.formatted.output&quot;, true);
		marshaller.marshal(books, System.out);
	}

}
</pre>
<p>Po uruchomieniu tego przykładu w konsoli powinien pokazać się taki oto wynik:</p>
<pre class="brush: xml;">
&lt; ?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;?&gt;
&lt;ns2_books xmlns:ns2=&quot;http://dywicki.pl/books&quot;&gt;
    &lt;book&gt;
        &lt;title&gt;Test title&lt;/title&gt;
        &lt;isbn&gt;111-111-111&lt;/isbn&gt;
        &lt;author&gt;
            &lt;firstname&gt;Martin&lt;/firstname&gt;
            &lt;lastname&gt;Fowler&lt;/lastname&gt;
        &lt;/author&gt;
        &lt;author&gt;
            &lt;firstname&gt;Łukasz&lt;/firstname&gt;
            &lt;lastname&gt;Dywicki&lt;/lastname&gt;
            &lt;type&gt;Translator&lt;/type&gt;
        &lt;/author&gt;
    &lt;/book&gt;
&lt;/ns2_books&gt;</pre>
<p>(Zamiast ns2_books powinno być ns2:books, ale narzędzie kolorujące składnie sobie nie radzi).</p>
<p>Dla zainteresowanych załączam <a href="http://media.dywicki.pl/blog/jaxb/jaxb-test.zip">źródła projektu</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2007/10/14/jaxb-2-wprowadzenie/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
	</channel>
</rss>

