<?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; XML</title>
	<atom:link href="http://blog.dywicki.pl/category/xml/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>Apache ServiceMix, Open Source ESB</title>
		<link>http://blog.dywicki.pl/2008/06/22/apache-servicemix-open-source-es/</link>
		<comments>http://blog.dywicki.pl/2008/06/22/apache-servicemix-open-source-es/#comments</comments>
		<pubDate>Sun, 22 Jun 2008 18:23:35 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[ESB]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Moje publikacje]]></category>
		<category><![CDATA[ServiceMix]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=215</guid>
		<description><![CDATA[Jakiś czas temu, jeszcze podczas pracy w poprzedniej firmie przypadło mi zadanie podpięcia się pod magistralę usług opartą o Apache Service Mix (SMX). Był to wówczas dla mnie temat zupełnie nowy, ba nawet nie wiedziałem z czym to się je. :) Koniec końców jednak podpięcie pod ESB (Enterprises Service Bus) nie było w ogóle trudne. [...]]]></description>
			<content:encoded><![CDATA[<p>Jakiś czas temu, jeszcze podczas pracy w poprzedniej firmie przypadło mi zadanie podpięcia się pod magistralę usług opartą o <a href="http://servicemix.apache.org">Apache Service Mix</a> (SMX). Był to wówczas dla mnie temat zupełnie nowy, ba nawet nie wiedziałem z czym to się je. :) Koniec końców jednak podpięcie pod <acronym title="Enterprise Service Bus">ESB</acronym> (Enterprises Service Bus) nie było w ogóle trudne. Po jakimś czasie i drobnych przetasowaniach na płaszczyźnie zawodowej zająłem się SMX-em nie jako klient magistrali a osoba implementująca usługi na szynie a ten wpis jest drobną przeróbką prezentacji, którą przygotowałem w pracy.<br />
<span id="more-215"></span></p>
<h3>Czym jest <acronym title="Enterprise Service Bus">ESB</acronym></h3>
<p>Jednoznaczne określenie terminu <acronym title="Enterprise Service Bus">ESB</acronym> nie jest łatwe, ponieważ wokół tego tematu rozpętana została burza marketingowa. Jedni uważają je za oś <acronym title="Service Oriented Architecture">SOA</acronym> (Service Oriented Architecture) inni jako zło konieczne w dużych instytucjach.</p>
<p>Dlatego pomijając teorię przejdźmy do najistotniejszych cech, jakie oferuje <acronym title="Enterprise Service Bus">ESB</acronym>, niezależnie od producenta oraz osoby definiującej pojęcie. Sam nie chciałbym wdawać się w dyskusję na temat postrzegania i <acronym title="Enterprise Service Bus">ESB</acronym> i <acronym title="Service Oriented Architecture">SOA</acronym>. </p>
<p><img src="http://blog.dywicki.pl/wp-content/uploads/2008/06/esb.jpg" alt="" title="esb" width="500" height="378" class="aligncenter size-full wp-image-217" /><br />
<em>Źródło - <a href="http://www.codeplex.com/esb">CodePlex</a></em></p>
<p>Na załączonym wyżej obrazku widać typową strukturę logiczną w oparciu o <acronym title="Enterprise Service Bus">ESB</acronym>. Z lewej strony mamy komercyjne rozwiązanie – <a href="http://www-306.ibm.com/software/integration/wmq/">MQ Series</a> firmy <a href="http://www.ibm.com/us/">IBM</a>, dalej idąc dołem, widzimy bazę danych, serwer pocztowy a na końcu mainframe. U góry natomiast pojawiają się klienci.</p>
<h3>Ciąg dalszy</h3>
<p>Na bazie tego obrazku można powiedzieć co nieco o tym, czym owa niebieska rurka symbolizująca <acronym title="Enterprise Service Bus">ESB</acronym> jest:</p>
<ul>
<li>Jest to z pewnością centralny rejestr usług firmy, dzięki któremu nie jest konieczne wiązanie aplikacji między sobą. Wiąże się je tylko i wyłącznie z jednym elementem – z magistralą.</li>
<li>Kolejny ważny punkt, to most pomiędzy protokołami. W dobie, gdy wszyscy żyją już Web Services nie można zapomnieć o innych sposobach komunikacji – poczynając od poczciwej <a href="http://pl.wikipedia.org/wiki/CORBA">Corby</a> po kolejki JMS czy też odczyt zasobów z <acronym title="File Transfer Protocol">FTP</acronym>.</li>
<li>Transformacja komunikatów to opcjonalna czynność, której nie widać na wyżej wymienionym obrazku. Jest ona wykonywana pod maską, wewnątrz magistrali, w zależności od potrzeb. W chwili gdy mamy komunikaty z systemu A do systemu B możemy wszystko sprowadzić do jednego uniwersalnego <acronym title="Application Programming Interface">API</acronym> danych.</li>
<li>Inteligentny router informacji. Większość magistral ma coś wspólnego z pojęciem EIP, czyli <a href="http://www.enterpriseintegrationpatterns.com/">Enterprise Integration Patterns</a>. Jednym z tych wzorców jest <a href="http://www.enterpriseintegrationpatterns.com/ContentBasedRouter.html">Content Based Router</a>, to znaczy w zależności od kształtu, zawartości komunikatu, nagłówka, fragmentu, czegokolwiek możemy odbijać komunikat w różnych kierunkach. Dalej z wzorców można wymienić <a href="http://www.enterpriseintegrationpatterns.com/Filter.html">Message Filter</a>, <a href="http://www.enterpriseintegrationpatterns.com/RecipientList.html">Recipient List</a>, <a href="http://www.enterpriseintegrationpatterns.com/RoutingTable.html">Routing Slip</a>, <a href="http://www.enterpriseintegrationpatterns.com/WireTap.html">Wire Tap</a>, <a href="http://www.enterpriseintegrationpatterns.com/Sequencer.html">Splitter</a>, <a href="http://www.enterpriseintegrationpatterns.com/Resequencer.html">Resequencer</a> itd.</li>
<li>Integrator procesów biznesowych (bardziej marketingowo) – po pierwsze odwzorowanie usług magistrali do czynności biznesowych w organizacji a po drugie wsparcie dla procesorów reguł biznesowych (<a href="http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wsbpel">WS-BPEL</a>).</li>
</ul>
<h3>Service Mix jako <acronym title="Enterprise Service Bus">ESB</acronym></h3>
<p>Mając zestaw wyżej wymienionych cech możemy przejść do omówienia projektu Apache Service Mix.<br />
Może na początku kilka słów o tym, czym jest JBI, ponieważ pojawia się sam skrót, ale nie ma jego omówienia.<br />
Otóż, <a href="http://jcp.org/en/jsr/detail?id=208">JBI</a> w rozwinięciu oznacza Java Business Integration. Jest to standard przyjęty w ramach <a href="http://jcp.org/">Java Community Process</a> w celu określenia norm budowania rozwiązań <acronym title="Service Oriented Architecture">SOA</acronym> (znów buzzword). Pomijając politykę wielkich korporacji oraz marketing przejdźmy do elementów, które standard ten określa:<br />
<img src="http://blog.dywicki.pl/wp-content/uploads/2008/06/msgflow3.png" alt="Źródło: Java.net" title="Komponenty JBI" align="center" /><br />
<em>Źródło <a href="http://download.java.net/general/open-esb/docs/jbi-admin-guide/">Open <acronym title="Enterprise Service Bus">ESB</acronym> Starter Kit</a></em></p>
<ul>
<li>Typy komponentów:
<ol>
<li>Service Engine (SE) – backend do obsługi zapytań.</li>
<li>Binding Components (BC) – frontend, do nasłuchiwania w danym standardzie.</li>
<li>Shared Libraries (SL) – kod współdzielony przez w/w komponenty.
<li>
<li>Service Assembly (SA) – zbiór usług rozumianych jako jedność przez magistralę (zwykle para BC+SE).</li>
</ol>
<li>Normalized Message Router – jest to serce rozwiązania opartego o JBI, ponieważ w nim są transportowane komunikaty. To on zapewnia przepływ informacji z komponentów bindujących do silników.</li>
<li>Message Exchange Patterns – w oparciu o definicję dla <acronym title="Simple Object Access Protocol">SOAP</acronym> JBI przewiduje następujące typy komunikatów:</li>
<ol>
<li>In-Only – tylko wejście, usługa nie zwraca żadnej odpowiedzi
<li>Rebust In-Only – zwrócony zostanie status po obsłudze zapytania bądź wyjątek.
<li>In-Out – standardowa obsługa wejście-wyjście.
<li>In Optional-Out – wejście z niewiążącą (nieobowiązkową) odpowiedzią.
    </ol>
</ul>
<p>Dostępnych jest kilka implementacji JBI:</p>
<ul>
<li><a href="https://open-esb.dev.java.net/">Open <acronym title="Enterprise Service Bus">ESB</acronym></a></li>
<li><a href="http://servicemix.apache.org">Apache Service Mix</a></li>
<li><a href="http://open.iona.com/products/enterprise-servicemix/">FUSE <acronym title="Enterprise Service Bus">ESB</acronym></a> (na bazie Service Mix)</li>
<li><a href="http://www.bostechcorp.com/products_cb_esb.htm">Bostech Chain Builder <acronym title="Enterprise Service Bus">ESB</acronym></a></li>
<li><a href="http://mule.mulesource.org/display/MULE/Home">Mule</a></li>
<li><a href="http://www.jboss.org/jbossesb/">JBoss <acronym title="Enterprise Service Bus">ESB</acronym></a></li>
<li><a href="http://www.oracle.com/products/middleware/index.html">Fusion Middleware</a></li>
<li><a href="http://www.tibco.com/software/soa/activematrix_service_bus/default.jsp">ActiveMatrix Service Bus</a></li>
</ul>
<h3>Service Mix od środka</h3>
<p>Wewnątrz Service Mix jest spięciem kilku potężnych projektów, rozwijanych od dłuższego czasu, które zdobyły już renomę i popularność. Między innymi można wyróżnić:</p>
<ul>
<li>Pierwszy z tych projektów to <a href="http://springframework.org/">Spring Framework</a>, rozwijany od bodajże 2000 roku, z powodzeniem rywalizujący z architekturami opartymi o EJB. Spring jest nie tylko mechanizmem konfiguracyjnym ale również zbiorem bardzo dobrych komponentów umożliwiających szereg operacji (bazy danych, JMS, przetwarzanie wsadowe, Web Services etc).</li>
<li>Drugi, bardzo ważny projekt to <a href="http://activemq.apache.org/">Active MQ</a>. Największa i najpopularniejsza otwarta implementacja standardu JMS. Jest on używany wewnątrz Service Mix-a jako transporter komunikatów w Normalized Message Router jak i do obsługi końcówek JMS.<br />
        - Wymieniony nieco niżej pod-projekt Active MQ to <a href="http://activemq.apache.org/camel/">Camel</a>. Jest to szkielet przeznaczony do tworzenia reguł routingu. Wspiera różnorakie transporty (<acronym title="HyperText Transfer Protocol">HTTP</acronym>, JMS, JBI, <acronym title="Microsoft">MS</acronym> MQ itp.).</li>
<li><a href="http://geronimo.apache.org/xbean/">XBean</a> jest fragmentem projektu Apache Geronimo (serwer aplikacyjny ze stajni Apache) przeznaczonym do tworzenia konfiguracji i zarządzania komponentami. Jest zbudowany w oparciu o Springa.</li>
<li><a href="http://cxf.apache.org/">Apache CXF</a> jest stosunkowo nowym projektem, który jest używany poprzez Service Mix w celu obsługi zapytań <acronym title="Simple Object Access Protocol">SOAP</acronym> (chociaż możliwe jest użycie innego komponentu).</li>
<li><a href="http://ode.apache.org/">Apache ODE</a> jest silnikiem reguł biznesowych w oparciu o WS-BPEL.</li>
<li>JBoss Drools jest kolejnym procesorem reguł biznesowych. Może być użyty do routingu. Jest dostępny plugin pozwalający na łatwą pracę z tą technologią.</li>
</ul>
<h3>Możliwości Service Mix</h3>
<p>Wyżej wymienione projekty są używane w Service Mix w celu uzyskania typowych funkcjonalności ESB:</p>
<ul>
<li><a href="http://servicemix.apache.org/servicemix-jms.html">JMS</a>, czyli obsługa kolejek</li>
<li><a href="http://servicemix.apache.org/servicemix-bpe.html">WS-BPEL</a>, obsługa reguł biznesowych</li>
<li>Web Services przy pomocy <a href="http://servicemix.apache.org/servicemix-cxf-se.html">CXF</a> jak i modułu <a href="http://servicemix.apache.org/servicemix-jsr181.html">JSR-181</a></li>
<li><a href="http://servicemix.apache.org/servicemix-saxon.html">Transformacje</a> <acronym title="eXtensible Stylesheet Language Transformations">XSLT</acronym> oraz XQuery (w oparciu o Saxona)</li>
<li><a href="http://servicemix.apache.org/servicemix-file.html">File Drop</a> to odczyt i zapis do plików dostępnych lokalnie jak i zdalnie (<a href="http://servicemix.apache.org/servicemix-ftp.html"><acronym title="File Transfer Protocol">FTP</acronym></a>)</li>
<li>Obsługa protokołu <a href="http://servicemix.apache.org/servicemix-xmpp.html">XMPP</a> pozwala na łatwą integrację z komunikatorami zbudowanymi w oparciu o Jabbera.</li>
<li>Dostęp do poczty przy pomocy modułu <a href="http://servicemix.apache.org/servicemix-mail.html">servicemix-mail</a></li>
<li>Komponenty programowe:</li>
<ul>
<li>Dają <a href="http://servicemix.apache.org/servicemix-bean.html">możliwość dopisania</a> własnych "endpointów", czyli implementacji docelowych usług bądź pośredników.</li>
<li>Dodatkowe funkcjonalności (cache, rss, walidacja)</li>
</ul>
<li><a href="http://servicemix.apache.org/servicemix-scripting.html">Języki skryptowe</a> (min <a href="http://groovy.codehaus.org/">Groovy</a>)</li>
</ul>
<h3><acronym title="Enterprise Service Bus">ESB</acronym> – dlaczego Open Source</h3>
<p>Wybór Service Mix-a nie był podyktowany przypadkiem. Jest to bowiem najpopularniejsze tego typu rozwiązanie z otwartym kodem źródłowym. Co więcej, nie jest to projekt rozwijany przez osoby bez doświadczenia, pozostawiony bez wsparcia.<br />
Otwarty kod ułatwia przede wszystkim adaptację tego rozwiązania do potrzeb organizacji a nie odwrotnie – organizacji do potrzeb magistrali. W razie potrzeb jesteśmy w stanie dopisać własne komponenty, obsługę mniej standardowych protokołów na bazie dostarczonych interfejsów czy to w Service Mix czy to w Camelu.<br />
Przyjęte standardy gwarantują ciągłość rozwoju oraz ułatwiają integrację (<a href="http://java.sun.com/javase/technologies/core/mntr-mgmt/javamanagement/">JMX</a> umożliwia łatwe podpięcie konsoli administracyjnej), podczas gdy <a href="http://en.wikipedia.org/wiki/J2EE_Connector_Architecture">J2EE Connector Architecture</a> definiuje kontrakty (zarządzanie połączeniami, transakcjami, bezpieczeństwem).<br />
Nie bez znaczenia jest również koszt, jaki organizacja ponosi w przypadku zdecydowania się na otwarte rozwiązanie. Rozpoczęcie prac z Service Mix-em kosztuje 0 PLN. Każdy, bez rejestracji, podawania jakichkolwiek danych może pobrać źródła albo gotowe dystrybucje i uruchomić je na swoim komputerze. W chwili gdy istnieje takie zapotrzebowanie, organizacja posiada kompetencje i skromny budżet to taka konfiguracja początkowo jest optymalna. Z biegiem czasu gdy zaistnieje konieczność wsparcia czy szkoleń to są one oferowane przez firmę IONA, która jest zaangażowana w rozwój Service Mix-a.</p>
<h3>Service Mix a bezpieczeństwo</h3>
<p>Większość, jeśli nie wszystkie rozwiązania w Javie, które wiążą się z kryptografią są oparte na JCA – <a href="http://java.sun.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html">Java Cryptography Architecture</a>. Jest to zestaw interfejsów oraz ich implementacji zawierający implementację najpopularniejszych algorytmów kryptograficznych jak i <acronym title="Application Programming Interface">API</acronym> umożliwiające tworzenie własnych rozszerzeń (<a href="http://java.sun.com/javase/technologies/security/">JCE</a>).<br />
Standard autoryzacji i uwierzytelniania w Javie to JAAS (<a href="http://java.sun.com/javase/6/docs/technotes/guides/security/jaas/JAASRefGuide.html">Java Authentication and Authorization Service</a>). W oparciu o niego jest budowanych większość rozwiązań związanych z bezpieczeństwem. Nawet największe alternatywy takie jak <a href="http://www.acegisecurity.org/">Acegi Security</a> (obecnie Spring Security posiadają adaptery integrujące je ze standardem). Przy użyciu dostępnych interfejsów możliwe jest dostarczenie własnej implementacji usługi obsługującej autoryzację bądź uwierzytelnianie użytkowników/systemów.<br />
Bezpieczeństwo usług sieciowych jest zależne od wybranego komponentu Service Mix. Pełne wsparcie dla WS-Security oferują komponenty zbudowane w oparciu o Apache CXF (szyfrowanie, podpisywanie komunikatów). Z innych standardów CXF wspiera także WS-Policy, WS-Addressing.<br />
Szyfrowane połączenia są łatwe do uzyskania przy pomocy komponentu <a href="http://servicemix.apache.org/servicemix-http.html">servicemi-http</a>.<br />
Dostępne zabezpieczenia na poziomie wirtualnej maszyny Javy to certyfikowanie (podpisywanie) kodu modułów oraz konfiguracja Security Managera (umożliwia wyłączenie dostępu do pakietów/klas/metod).</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2008/06/22/apache-servicemix-open-source-es/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Agavi IDE, db4o 7.0, ObjectNotStorableException i Ant :)</title>
		<link>http://blog.dywicki.pl/2007/11/30/agavi-ide-db4o-70-objectnotstorableexception-i-ant/</link>
		<comments>http://blog.dywicki.pl/2007/11/30/agavi-ide-db4o-70-objectnotstorableexception-i-ant/#comments</comments>
		<pubDate>Thu, 29 Nov 2007 23:21:25 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Agavi]]></category>
		<category><![CDATA[DB]]></category>
		<category><![CDATA[Inne]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Wiadomości]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=201</guid>
		<description><![CDATA[Dnia dzisiejszego zmobilizowałem się by nieco popracować nad modelem dla Agavi IDE. Jest to podstawa bez której ciężko budować kolejne edytory. Trzeba w końcu wiedzieć jakie akcje, widoki etc są w projekcie by sugerować użytkownikowi poprawne wartości. Jak donosi Michał Mech na swoim blogu, konkurencja nie śpi i wszczęła prace nad integracją Eclipse i Symfony [...]]]></description>
			<content:encoded><![CDATA[<p>Dnia dzisiejszego zmobilizowałem się by nieco popracować nad modelem dla Agavi IDE. Jest to podstawa bez której ciężko budować kolejne edytory. Trzeba w końcu wiedzieć jakie akcje, widoki etc są w projekcie by sugerować użytkownikowi poprawne wartości.<br />
Jak donosi <a href="http://michalmech.pl">Michał Mech</a> na <a href="http://michalmech.pl/index.php/2007/11/29/symfoclipse-wsparcie-dla-symfony-na-platformie-eclipse/">swoim blogu</a>, konkurencja nie śpi i wszczęła prace nad integracją Eclipse i Symfony - tak też narodziło się <a href="http://">Symfoclipse</a>. Stąd straciłem już palmę pierwszeństwa i pozostaje mi walczyć na polu jakości i funkcjonalności. <a href="http://zend.com">Zend</a> również serwuje wsparcie dla <a href="http://framework.zend.com/">Zend Framework</a>, aczkolwiek po <a href="http://www.zend.com/webinar/studio/EN_11_Zend_Studio_Neon_Zend_Framework_Support/">prezentacji</a> miałem mieszane uczucia. Przede wszystkim lektor mówiący z paskudnym angielskim akcentem. Nie wiem, może jestem wyczulony, ale gdy słyszę te fonetyczne wygibasy to mnie to mierzi, może dla jednych to plus, ale dla mnie lepszym sprzedawcą produktu jest ktoś kto mówi o swoim projekcie chociażby z francuskim akcentem niż wynajęty lektor, który ma pomnożyć wrażenie "powagi" przedsięwzięcia. Na drugim miejscu jakość "wsparcia", bo inaczej jak w cudzysłowach tego nie mogę określić, jest po prostu żenująca. Czy mi się wydaje czy oni każą sobie płacić za dodanie kreatora (wizzarda)? ;) Coś mi się wydaje, że załoga <a href="http://phpeclipse.de/"><acronym title="Pre-Hypertext Processing">PHP</acronym> Eclipse</a> dobrze robi ponownie zwierając szyki!</p>
<p>Oczywiście przy pisaniu napotkałem problemy. Pierwszym z nich było zniknięcie klasy buildera, drugim wywalanie się db4o (dev 7.0). O ile pierwszy uraczył mnie gromadą logów o tyle drugi poza pokaźnym stosem nie dał mi nic. Typ wyjątku <b>com.db4o.ext.ObjectNotStorableException</b> - nazwa w miarę jasna, problem w tym, że za tym żadnego uzasadnienia, powodu dla którego wyjątek by leciał. Zero, dosłownie zero informacji.<br />
Na forum db4o znalazłem parę postów - z nich wyciągnąłem wniosek - konieczne jest użycie taska ant, który zmodyfikuje bytecode klasy, ponieważ w przeciwnym wypadku db4o próbuje serializować obiekt, a gdy mu się nie uda rzuca w/w wyjątek.</p>
<p>Skrypt ant - który załatwia problem, dla potomnych (<a href="http://developer.db4o.com/forums/thread/43766.aspx">przeróbka z forum</a>):</p>
<pre class="brush: xml;">&lt;project name=&quot;db4o enhance project&quot; default=&quot;enhance&quot; basedir=&quot;.&quot;&gt;

	&lt;!-- inny projekt z workspace'a --&gt;
	&lt;property name=&quot;model.classes.location&quot; location=&quot;E:/agavi-ide/org.codehouse.model&quot; /&gt;
	&lt;!--
	położenie eclipse, db4o szpera w poszukiwaniu zależności klas, tak się składa,
	że mój kod korzysta z paru rzeczy z org.eclipse.core.resources, normalnie ta
	wstawka się nie pojawia
	--&gt;
	&lt;property name=&quot;eclipse.location&quot; location=&quot;E:/eclipse-3.3/eclipse&quot; /&gt;

	&lt;target name=&quot;pack-model&quot;&gt;
		&lt;echo message=&quot;Tworzę archiwum z modelem&quot; /&gt;
	    &lt;jar destfile=&quot;lib/model.jar&quot;&gt;
	        &lt;fileset dir=&quot;${model.classes.location}/bin/&quot;&gt;
	        	&lt;!-- włączamy wszystkie skomilowane klasy --&gt;
	            &lt;include name=&quot;**/*.class&quot; /&gt;
	        &lt;/fileset&gt;
	    &lt;/jar&gt;
	&lt;/target&gt;

	&lt;!-- classpath dla projektu --&gt;
	&lt;path id=&quot;project.classpath&quot;&gt;
		&lt;pathelement path=&quot;${basedir}/bin&quot; /&gt;
		&lt;fileset dir=&quot;lib&quot;&gt;
			&lt;include name=&quot;**/*.jar&quot; /&gt;
		&lt;/fileset&gt;
		&lt;fileset dir=&quot;${eclipse.location}/plugins/&quot;&gt;
			&lt;include name=&quot;**/*.jar&quot; /&gt;
		&lt;/fileset&gt;
	&lt;/path&gt;

    &lt;!-- odwołanie do taska z db4o-tools.jar --&gt;
    &lt;taskdef name=&quot;db4o-enhance&quot; classname=&quot;com.db4o.enhance.Db4oEnhancerAntTask&quot; classpathref=&quot;project.classpath&quot; /&gt;

	&lt;target name=&quot;enhance&quot; depends=&quot;pack-model&quot;&gt;
		&lt;!-- przeoranie źródeł i zależności --&gt;
		&lt;db4o -enhance classtargetdir=&quot;${basedir}/bin&quot; jartargetdir=&quot;${basedir}/lib&quot;&gt;
			&lt;classpath refid=&quot;project.classpath&quot; /&gt;
			&lt;sources dir=&quot;${basedir}/bin&quot; /&gt; &lt;!-- w tym katalogu db4o zajmie się plikami .class --&gt;
			&lt;jars dir=&quot;${basedir}/lib&quot;&gt;
				&lt;include name=&quot;*.jar&quot; /&gt;
				&lt;exclude name=&quot;db4o-*.jar&quot; /&gt;
				&lt;exclude name=&quot;ant.jar&quot; /&gt;
				&lt;exclude name=&quot;bloat-1.0.jar&quot; /&gt;

			&lt;/jars&gt;
		&lt;/db4o -enhance&gt;
	&lt;/target&gt;

&lt;/project&gt;</pre>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2007/11/30/agavi-ide-db4o-70-objectnotstorableexception-i-ant/feed/</wfw:commentRss>
		<slash:comments>0</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>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>
		<item>
		<title>Wygodny edytor do konfiguracji XML</title>
		<link>http://blog.dywicki.pl/2007/08/02/wygodny-edytor-do-konfiguracji-xml/</link>
		<comments>http://blog.dywicki.pl/2007/08/02/wygodny-edytor-do-konfiguracji-xml/#comments</comments>
		<pubDate>Thu, 02 Aug 2007 21:46:17 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Agavi]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=176</guid>
		<description><![CDATA[Konfiguracja w XMLu ma swoje plusy jak i minusy. Nie jest tak banalna w obsłudze jak zapisana w PHP czy w .ini, ale daje dość spore możliwości. Troszkę dywagacji na ten temat było jakiś czas temu w poście pod tytułem "Dlaczego konfiguracja w XML". Jednym z problemów związanych z XMLem jest konieczność zapamiętania nazw znaczników [...]]]></description>
			<content:encoded><![CDATA[<p><a href='http://blog.dywicki.pl/wp-content/uploads/2007/08/xml-catalog.PNG' title='Zdefiniowany katalog ze schematami XML' style="border: 0px" rel="lightbox"><img src='http://blog.dywicki.pl/wp-content/uploads/2007/08/xml-catalog.thumbnail.PNG' alt='Zdefiniowany katalog ze schematami XML' style="margin: 0px" rel="lightbox" align="left" /></a>Konfiguracja w XMLu ma swoje plusy jak i minusy. Nie jest tak banalna w obsłudze jak zapisana w <acronym title="Pre-Hypertext Processing">PHP</acronym> czy w .ini, ale daje dość spore możliwości. Troszkę dywagacji na ten temat było jakiś czas temu w poście pod tytułem "<a href="http://blog.dywicki.pl/?p=101">Dlaczego konfiguracja w <acronym title="eXtensible Markup Language">XML</acronym></a>".<span id="more-176"></span><br />
Jednym z problemów związanych z XMLem jest konieczność zapamiętania nazw znaczników i atrybutów, co powoduje z początku problemy. Pisanie w XMLu nie jest wówczas tak wygodne jak w <acronym title="Pre-Hypertext Processing">PHP</acronym> (z resztą nigdy takie nie będzie), ale możemy je sobie uprościć przy pomocy dwóch opcji jakie oferuje edytor <acronym title="eXtensible Markup Language">XML</acronym> dostępny przez <a href="http://www.eclipse.org/webtools/wst/main.php">WST</a>.</p>
<p><a href='http://blog.dywicki.pl/wp-content/uploads/2007/08/catalog-entry.PNG' title='Dodanie nowego wpisu' style="border: 0px" rel="lightbox"><img src='http://blog.dywicki.pl/wp-content/uploads/2007/08/catalog-entry.thumbnail.PNG' alt='Dodanie nowego wpisu' style="margin: 0px" rel="lightbox" align="left" /></a>Pierwszym krokiem jest podpięcie własnych plików z definicjami struktur do Eclipse. Wskakujemy zatem do <b>Window &gt; Preferences</b> a następnie do <b>Web and <acronym title="eXtensible Markup Language">XML</acronym> &gt; <acronym title="eXtensible Markup Language">XML</acronym> Catalog</b>. Mamy tam listę definicji, których używa WST do podpowiadania składni. Jest miejsce na definicje użytkownika - zatem dorzucamy nowy wpis do obsługi autoload. Po pierwsze wybieramy nowy element. Do wyboru mamy dwa rodzaje źródeł - plik ze wskazanego projektu bądź z określonej lokalizacji. Drugi ma tą przewagę, że nie ma problemów z jego przenoszeniem pomiędzy różnymi workspace'ami. Po wskazaniu źródła z poprawnym dokumentem xsd bądź dtd Eclipse samo wypełni pola. Jedyne co pozostaje nam zrobić to kliknąć i potwierdzić.</p>
<p><a href='http://blog.dywicki.pl/wp-content/uploads/2007/08/new-file.PNG' title='Tworzenie nowego pliku ze schematu' style="border: 0px" rel="lightbox"><img src='http://blog.dywicki.pl/wp-content/uploads/2007/08/new-file.thumbnail.PNG' alt='Tworzenie nowego pliku ze schematu' style="margin: 0px" rel="lightbox" align="right" /></a>Po tym zabiegu możemy zabrać się za edytowanie istniejących plików bądź stworzyć nowy w oparciu o kreator.. Aby to zrobić korzystamy z opcji <b>File &gt; New &gt; Other</b> z listy wybieramy <acronym title="eXtensible Markup Language">XML</acronym> i tworzymy na podstawie schematu. Po wybraniu tej opcji mamy dostępną listę schematów, na podstawie których WST jest w stanie wygenerować szablon dokumentu.</p>
<p><a href='http://blog.dywicki.pl/wp-content/uploads/2007/08/xml-editing.PNG' title='Efekt naszych prac - podpowiadanie składni' style="border: 0px" rel="lightbox"><img src='http://blog.dywicki.pl/wp-content/uploads/2007/08/xml-editing.thumbnail.PNG' alt='Efekt naszych prac - podpowiadanie składni' style="margin: 0px" rel="lightbox" align="left" /></a> Koniec końców mamy w pełni funkcjonalne podpowiadanie składni w dokumencie <acronym title="eXtensible Markup Language">XML</acronym>. W podpowiedziach jest również dodawana informacja o krotności elementów * (zero i więcej), + (jeden i więcej), ? (zero lub jeden) a także wyświetlana dokumentacja. Gdy pracuje się z dobrze opisanym schematem - np plikiem xsd, w którym autorzy nie żałowali miejsca na adnotacje z informacjami na temat poszczególnych elementów - nie ma nawet konieczności skakania po oknach w celu doczytania informacji - jakiego atrybutu bądź znacznika użyć - po prostu mamy to od razu w edytorze. Bez jakiegokolwiek wysiłku, kilkoma kliknięciami zyskujemy funkcjonalne narzędzie. :)</p>
<p><a href='http://blog.dywicki.pl/wp-content/uploads/2007/08/template.PNG' title='Definicja szablonu' style="border: 0px" rel="lightbox"><img src='http://blog.dywicki.pl/wp-content/uploads/2007/08/template.thumbnail.PNG' alt='Definicja szablonu' rel="lightbox" style="margin: 5px" align="right" /></a>Druga opcja, która jest dostępna w większości edytorów tekstowych to zdefiniowane szablony. W celu zdefiniowania nowego szablonu w preferencjach otwieramy zakładkę <b>Web and <acronym title="eXtensible Markup Language">XML</acronym> &gt; <acronym title="eXtensible Markup Language">XML</acronym> Files &gt; Templates</b>. Znajdziemy tam listę z możliwością modyfikacji. Opcję tą odkryłem przy okazji walczenia z pisaniem schema.xml dla Propela z ręki. Była niezastąpiona i zastępowała sporo pracy związanej z tępym kopiowaniem tekstu.<a href='http://blog.dywicki.pl/wp-content/uploads/2007/08/template-usage.PNG' title='Szablon w akcji!' style="border: 0px" rel="lightbox"><img src='http://blog.dywicki.pl/wp-content/uploads/2007/08/template-usage.thumbnail.PNG' alt='Szablon w akcji!' rel="lightbox" style="margin: 5px" align="left"  /></a> W definicji szablonów mamy do dyspozycji kilka pre definiowanych zmiennych, są one przydatne podczas tworzenia szablonów nowych plików. Możemy również deklarować własne zmienne - <b>${nazwa_zmiennej}</b>. Po wstawieniu szablonu do pliku możemy się nawigować po miejscach wystąpień zmiennych przy użyciu tabulatora. Miejsca, w których powtarzają się te same nazwy zmiennych są automatycznie uzupełniane, tak, że wpisując przy pierwszej zmiennej ${name} nie musimy powtarzać tej czynności w drugim miejscu.</p>
<p>Mam nadzieję, że przyda się w praktyce! Przy okazji pragnę Was, drodzy czytelnicy, poprosić o opinie na temat lightboxa, czy nie przeszkadza Wam jego użycie, być może wolicie tradycyjne linki do plików? Pomijam efekty graficzne, bo wygaszanie tła etc przy trzecim razie bardziej irytuje niż cieszy oko. Jak sądzicie - usunąć lightboxa? Momentami mam też problemy z rozmieszczaniem "obrazków" stąd są prozżucane po akapitach raz z lewej raz z prawej ponieważ przy mniejszych rozdzielczościach zachodzą na siebie, co powoduje niezbyt miłe efekty.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2007/08/02/wygodny-edytor-do-konfiguracji-xml/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Dlaczego konfiguracja w XML.</title>
		<link>http://blog.dywicki.pl/2006/09/07/dlaczego-konfiguracja-w-xml/</link>
		<comments>http://blog.dywicki.pl/2006/09/07/dlaczego-konfiguracja-w-xml/#comments</comments>
		<pubDate>Thu, 07 Sep 2006 20:39:15 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Wiadomości]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/2006/09/07/dlaczego-konfiguracja-w-xml/</guid>
		<description><![CDATA[W czasach kiedy najbardziej trendy jest YAML twierdzę, że jest on niczym w porównaniu do tego, co oferuje XML. DLaczego? Dlatego, że tworząc dowolny dokument XML mogę go w bardzo prosty sposób rozszeżyć. Jak? Poprzez XInclude. Jego obsługa jest nawet w PHP więc nie ma z tym jakichkolwiek problemów. Definiuję tylko odnośnik i mam dołączony [...]]]></description>
			<content:encoded><![CDATA[<p>W czasach kiedy najbardziej trendy jest YAML twierdzę, że jest on niczym w porównaniu do tego, co oferuje <acronym title="eXtensible Markup Language">XML</acronym>. DLaczego?</p>
<p>Dlatego, że tworząc dowolny dokument <acronym title="eXtensible Markup Language">XML</acronym> mogę go w bardzo prosty sposób rozszeżyć. Jak? Poprzez XInclude. Jego obsługa jest nawet w <acronym title="Pre-Hypertext Processing">PHP</acronym> więc nie ma z tym jakichkolwiek problemów. Definiuję tylko odnośnik <xi :include xhref="localfile.xml" /> i mam dołączony ten XML [po wykonaniu $DOMDocument->xinclude();].</p>
<p>Kolejna sprawa. Walidacja. Nie muszę tworzyć żadnego kodu w <acronym title="Pre-Hypertext Processing">PHP</acronym> by sprawdzić poprawność XMLa. Wystarczy, że stworzę dobry schemat w XSD i mam walidację załatwioną bez jakiegokolwiek warunku. Do tego dochodzą ograniczenia takie jak rekurencja. W <acronym title="Pre-Hypertext Processing">PHP</acronym>  muszę to załatwiać poprzez wielokrotne wywołanie funkcji, które za każdym razem wydłuża czas. Normalnie załatwi mi to <acronym title="Document Object Model">DOM</acronym> <acronym title="eXtensible Markup Language">XML</acronym>, który jest napisany w C i będzie znacznie szybszy.</p>
<p>Parę linijek kodu i moja konfiguracja zapisana w XMLu stanie się czytelna dla oka przy użyciu <acronym title="eXtensible Stylesheet Language Transformations">XSLT</acronym> w połączeniu z <acronym title="Pre-Hypertext Processing">PHP</acronym>.<br />
Także czy dalej YAML i INI jest najlepszym sposobem przechowywania konfiguracji? Moim zdaniem nie - i nigdy nie będzie. <acronym title="eXtensible Markup Language">XML</acronym> jest technologią, która fakt faktem, jest nadmiarowa, ale oferuje bardzo dużą popularność. Można mówić, że YAML jest czytelny i przyjazny, ale nie oferuje takiej funkcjonalności przy takim małym nakładzie sił. <acronym title="eXtensible Markup Language">XML</acronym> jest wszędzie, jest prosty. Sprawdzanie poprawności dokumentu można załatwić poprzez inny <acronym title="eXtensible Markup Language">XML</acronym> a jego prezentacje poprzez kolejny, także znajomość technologii związanych z XMLem jest niewątpliwie przydatna.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2006/09/07/dlaczego-konfiguracja-w-xml/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>7 grzechów głównych PHP, XML</title>
		<link>http://blog.dywicki.pl/2006/07/18/7-grzechow-glownych-php-xml/</link>
		<comments>http://blog.dywicki.pl/2006/07/18/7-grzechow-glownych-php-xml/#comments</comments>
		<pubDate>Mon, 17 Jul 2006 22:21:10 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[7 grzechów]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Wiadomości]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/2006/07/18/7-grzechow-glownych-php-xml/</guid>
		<description><![CDATA[Na początku odpowiedź na post, który napisał Zyx. Aktualnie każdy, kto chce napisać nowe rozszerzenie do PHP, musi tylko znać język C, znać cel swej pracy oraz przeczytać rozdział 46 dokumentacji PHP zatytułowany "Zend API: Hacking the Core of PHP" i poświęcony właśnie tworzeniu modułów. Zend API to nie wszystko. Moduły kompilowane nie są wyjściem [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Na początku odpowiedź na post, który napisał <a href="http://www.zyxist.com/pokaz.php/7_grzechow_php_komentarz">Zyx</a>. </strong></p>
<p><em>Aktualnie każdy, kto chce napisać nowe rozszerzenie do <acronym title="Pre-Hypertext Processing">PHP</acronym>, musi tylko znać język C, znać cel swej pracy oraz przeczytać rozdział 46 dokumentacji <acronym title="Pre-Hypertext Processing">PHP</acronym> zatytułowany "Zend API: Hacking the Core of <acronym title="Pre-Hypertext Processing">PHP</acronym>" i poświęcony właśnie tworzeniu modułów.</em></p>
<p>Zend <acronym title="Application Programming Interface">API</acronym> to nie wszystko. Moduły kompilowane nie są wyjściem super-uniwersalnym. Na co drugim serwerze nie ma opcji by dorzucić własne rozszerzenie. Wiele modułów z PECLa leży tam od lat, są one praktycznie nie rozwijane, także ich ilość niewiele może poświadczyć.</p>
<p><em>Projekt ten nie miał nigdy poprawiać po egoistycznie nastawionych twórcach baz danych oraz ich kreatywnym podejściu do implementacji standardu ANSI <acronym title="Structured Query Language">SQL</acronym>, ale na plus należy zaznaczyć, że niektóre braki bibliotek klienckich są emulowane (np. podpinanie). </em></p>
<p>Nikt nie mówi, że PDO miałoby to poprawiać. Spójrz na JDBC, producenci baz samodzielnie dostarczają sterowników do połączeń i dbają o to by były zgodne z własną bazą oraz kolejnymi standardami w JDBC.</p>
<p><em>Ale głupotą byłoby negowanie go tylko dlatego, że w kwestiach wielkoskalowych ma braki, a Zend ostatnio stosuje dziwne podejście w kwestii doboru priorytetów i debugowania swego sztandarowego projektu.</em></p>
<p>Diabeł tkwi w szczegółach. Brak stosownych narzędzi i rozwiniętych rozwiązań technologicznych jest sporym problemem, który znacznie utrudnia tworzenie aplikacji.</p>
<p><strong><acronym title="eXtensible Markup Language">XML</acronym> i SAX</strong><br />
SAX jest świetnym standardem. Niestety, ustawianie gromady opcji dla parsera to jakaś porażka. Do tego domyślne zmienianie nazw tagów na wielkie litery.. jak by ktoś z tego korzystał.<br />
SAX mógłby być świetnym rozwiązaniem, gdyby istniała klasa domyślnego parsera, która wymuszałaby implementacje tylko 2 metod - startElement i endElement. Niestety, jesteśmy skazani na to co, jest w PEAR, czyli kod pisany pod <acronym title="Pre-Hypertext Processing">PHP</acronym> 4.<br />
Poza tym problem z SAXem w <acronym title="Pre-Hypertext Processing">PHP</acronym> jest taki, że jeśli ktoś chce korzystać z przestrzeni nazw w dokumencie, którego używa ma niewielkie szanse na to, że cokolwiek uda mu się ugrać, ponieważ parser nie przekazuje do handlera informacji o tym do jakiej przestrzeni nazw należy tag. <span lang="EN-US">Dla przykładu w Javie metoda startElement wygląda w następujący sposób:</span></p>
<p>void startElement(string uri, string localname, string qname, attributes atts)<br />
a w <acronym title="Pre-Hypertext Processing">PHP</acronym><br />
void startElementImpl(resource parser, string localname, array atts)<br />
czyli zupełnie tak samo jak by tych przestrzeni nie było. Jedyny sposób to wyciąganie prefiksu w nazwie (bo otrzymujemy np foo:bar) i sprawdzanie względem wcześniej zdefiniowanych poprzez xmlns.<br />
<!--[if !supportLineBreakNewLine]--><br />
<!--[endif]--></p>
<p><strong><acronym title="Document Object Model">DOM</acronym></strong><br />
Za implementację <acronym title="Document Object Model">DOM</acronym> Panom z Zenda należą się gratulacje, przede wszystkim dlatego, że w końcu jest to moduł doprowadzony do standardu, zgodnie z zaleceniami <acronym title="World Wide Web Consortium">W3C</acronym>. Nie będę już narzekał, że jest to <acronym title="Document Object Model">DOM</acronym> Level 2 a nie 3 co by nie było, że się za wiele czepiam ;). Świetnie, że <acronym title="Document Object Model">DOM</acronym> jest częścią Core <acronym title="Pre-Hypertext Processing">PHP</acronym>. Nie ma problemów z tym, czy <acronym title="Document Object Model">DOM</acronym> jest czy nie.</p>
<p>Testując <acronym title="Document Object Model">DOM</acronym> przed napisaniem tej noty trafiłem na błąd w obsłudze encji. Działają one w atrybutach ale nie w treści. Sprawa wygląda w ten sposób, że encje predefiniowane takie jak &quote; są widoczne, zatem gdzie są moje? Uciekły bo się przestraszyły tagów.</p>
<p><strong>SimpleXML</strong><br />
SimpleXML jest bramką pomiędzy <acronym title="Document Object Model">DOM</acronym> a SAX. Oferuje mniejszą funkcjonalność niż <acronym title="Document Object Model">DOM</acronym>, ale wymaga o wiele mniej pracy niż SAX. Po prostu, wczytujesz plik i działa. Niestety, nie jest tak różowo. W nim również znalazłem niedoróbkę. Nie jestem pewien czy nie została ona załatana, problem polegał na gubieniu atrybutu przy kolekcji. Denerwuje mnie również to, że nikną mi informacje o przestrzeni nazw. Jeśli przeglądam dokument iteracyjnie tracę informację o tym z jakiej przestrzeni jest element.</p>
<p><strong><acronym title="eXtensible Stylesheet Language Transformations">XSLT</acronym></strong><br />
Zbyt małe możliwości połączenia <acronym title="Pre-Hypertext Processing">PHP</acronym> i samego procesu transformacji. Do <acronym title="eXtensible Stylesheet Language Transformations">XSLT</acronym> można przekazać tylko ciągi, zatem nie ma mowy o tym by wrzucić tablicę i na jej podstawie wykonać jakąś iterację. Niestety, nie te czasy. Plusem jest to, że można tworzyć funkcje do których parser potrafi się odwołać.. niestety są to albo funkcje albo statyczne odwołania do klas.</p>
<p><strong><acronym title="eXtensible Stylesheet Language">XSL</acronym>-FO</strong><br />
<acronym title="eXtensible Stylesheet Language">XSL</acronym>-FO to standard, który umożliwia przekształcenie dowolnego dokumentu <acronym title="eXtensible Markup Language">XML</acronym> do postaci binarnej takiej jak <acronym title="Portable Document Format">PDF</acronym>. Niestety w <acronym title="Pre-Hypertext Processing">PHP</acronym> nie doczekaliśmy się jeszcze żadnej implementacji tego standardu, poza jedną klasą w PEAR, która usiłuje wykonać transformację przy użyciu Javy.</p>
<p><strong>XSD</strong><br />
Z XSD w <acronym title="Pre-Hypertext Processing">PHP</acronym> jest zasadniczy problem. Nie istnieje. Można sprawdzić czy dokument jest zgodny ze schematem korzystając chociażby z DOMa, niestety nie ma żadnych narzędzi, które umożliwiają tworzenie klas ze schematu. Skala problemu znacznie się powiększa w chwili gdy korzystamy z <acronym title="Web Services Description Language">WSDL</acronym>, które pośrednio korzysta z XSD. Nie ma opcji, żeby stworzyć jakikolwiek typ złożony w <acronym title="Pre-Hypertext Processing">PHP</acronym> bez własnego kodu.</p>
<p>Rozbudowa o przykłady, być może wkrótce.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2006/07/18/7-grzechow-glownych-php-xml/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

