<?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>PINC-Blog &#187; Java</title>
	<atom:link href="http://www.pincservices.de/wordpress/category/java/feed" rel="self" type="application/rss+xml" />
	<link>http://www.pincservices.de/wordpress</link>
	<description>yet another developer blog</description>
	<lastBuildDate>Sat, 10 Sep 2011 07:53:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>Quelle aller Worte: Internationalisierung mit GWT UIBinder</title>
		<link>http://www.pincservices.de/wordpress/quelle-aller-worte-internationlisierung-mit-gwt-uibinder</link>
		<comments>http://www.pincservices.de/wordpress/quelle-aller-worte-internationlisierung-mit-gwt-uibinder#comments</comments>
		<pubDate>Sat, 10 Sep 2011 07:49:49 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Softwaredesign]]></category>
		<category><![CDATA[Webentwicklung]]></category>
		<category><![CDATA[gwt]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[internationalization]]></category>
		<category><![CDATA[LocalizableResource]]></category>
		<category><![CDATA[UIBinder]]></category>

		<guid isPermaLink="false">http://www.pincservices.de/wordpress/?p=581</guid>
		<description><![CDATA[Als Gott sah was beim Turmbau zu Babel passierte, entschied er sich die Sprache der Menschen zu teilen, so dass der Eine den Anderen nicht mehr verstehen möge. Ähnlich scheinen sich die Designer von GWT gefühlt haben, als sie die Internationalisierung von GWT 2.x entworfen haben. Das Internationalisierungsprinzip von GWT ist an sich sehr einfach. [...]]]></description>
			<content:encoded><![CDATA[<p>Als Gott sah was beim Turmbau zu Babel passierte, entschied er sich die Sprache der Menschen zu teilen, so dass der Eine den Anderen nicht mehr verstehen möge. Ähnlich scheinen sich die Designer von GWT gefühlt haben, als sie die Internationalisierung von GWT 2.x entworfen haben.</p>
<p>Das Internationalisierungsprinzip von GWT ist an sich sehr einfach. Man nehme ein paar <code>properties</code>-Dateien, inkludiere das I18N-Modul und lasse sich die entsprechende Java-Datei generieren. Soweit so gut. Leider nicht so, wenn man den UIBinder verwenden möchte. Hier haben sich bereits diverse verzweifelte Entwickler einen &#8220;abgebrochen&#8221; um herauszufinden, welche Dateien an welcher Stelle liegen müssen, damit man in den jeweiligen <code>ui.xml</code>-Dateien eine vernünftige Übersetzung erhält. </p>
<p>Grundsätzlich gilt, dass Übersetzungs-Keys aus <code>ui.xml</code>-Dateien immer im Package <code>com.google.gwt.i18n.client</code> mit dem Namen <code>LocalizableResource_[locale].properties</code> liegen müssen. Diesen Umstand verdanken wir dem <code>MessagesWriter</code>, der vom <code>UiBinderGenerator</code> herangezogen wird. Dieser generiert zwar die Messages-Dateien für alle Keys, die sich in einer <code>ui.xml</code>-Datei befinden in eine eigene <code>Messages</code>-Klasse, importiert aber mittels</p>
<pre class="brush: plain;">
writer.write(&quot;import static com.google.gwt.i18n.client.LocalizableResource.*;&quot;);
</pre>
<p>ausschließlich die Übersetzungen aus <code>LocalizableResource</code>. Soweit so gut, möchte man meinen. Problematisch wird es dann, wenn man Übersetzungen sowohl im Java-Code, als auch im in den ui-Dateien haben will. Typisches Beispiel sind hier Tabellen vom Typ <code>CellTable</code>, deren Spalten normalerweise in den View-Klassen definiert werden. Will man hier nun sprachlich angepasste Spaltenköpfe haben, muss man diese mittels einer <code>Messages</code>-Klasse übersetzen.<br />
In diesem Moment steht man vor der Frage: Möchte ich zwei Übersetzungsdateien verwalten, in denen ggf. Keys doppelt auftreten, oder möchte ich nur Eine für beide Mechanismen haben?</p>
<p>Ohne auf die unsäglichen und teilweise unpraktikablen Varianten einzugehen, die sich im Netz bereits befinden bzw. die kryptisch auf der GWT-Dokumentation vorgestellt wurde, stelle ich hier meine zwei Lösungen vor, die ich für sinnvoll erachte.</p>
<h3>Variante 1: <code>ui:with</code></h3>
<p>Die klassische Variante. Man nehme einfach die existierenden Messages und importiere sie wie folgt in die <code>ui.xml</code>-Datei.</p>
<pre class="brush: plain;">
 &lt;ui:with field='messages' type='com.my.app.MyMessages'/&gt;
 &lt;g:Label text=&quot;{messages.hello}&quot; /&gt;
</pre>
<p>Diese Variante hat den Vorteil, dass man auf die komplette Bandbreite der Erweiterungen, die für <code>Messages</code>-Klassen bereitgestellt wurde zugreifen kann. </p>
<h3>Variante 2: Customized <code>Messages</code>-Interface</h3>
<p>In Variante 1 nutzen wir den Mechanismus, der eigentlich für den Java-Code gedacht war für den UiBinder. Natürlich geht es auch anders herum. Wir &#8220;kopieren&#8221; einfach den Mechanismus der <code>MessagesWriter</code>-Klasse. Wir bauen uns ein Interface und importieren die LocalizableResources.</p>
<pre class="brush: plain;">
package com.mypackage;

import static com.google.gwt.i18n.client.LocalizableResource.*;

public interface MyAppMessages extends Messages {
  @DefaultMessage(&quot;Example&quot;)
  String example();
}
</pre>
<p>Der GWT-Compiler greift hier einfach das Interface und verknüpft die Methoden mit den Keys aus der jeweiligen LocalizableResource-Datei. Damit lassen sich auch innerhalb von Java-Dateien die Keys aus LocalizableResource verwenden.</p>
<p><b>Achtung:</b><br />
<i>Leider gibt es nicht die Möglichkeit LocalizableResource-Dateien über den i18n-Aufruf in eine Klasse übersetzen zu lassen, da <code>LocalizableResource</code> bereits ein existierendes Interface ist und die Übersetzung zu einer sogenannten zyklischen Vererbung führt.</i></p>
<h3>Fazit</h3>
<p>Mit beiden Varianten lässt sich das bestehende Problem lösen, dass man nur einen Mechanismus zur Internationalisierung innerhalb von GWT-Projekten nutzen möchte. Welche der beiden zum Einsatz kommt hängt stark von der bestehenden Struktur und &#8211; was nicht zur vernachlässigen ist &#8211; von der Motivation des Entwicklers, welche Schritte für ihn in seinem Arbeitsprozess besser integriert werden können, ab. Während Variante 1 den Aufruf des i18n-Creators erfordert, muss in Variante 2 das Interface immer manuell angepasst werden.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pincservices.de/wordpress/quelle-aller-worte-internationlisierung-mit-gwt-uibinder/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java + Groovy: Sample-Project PdfRenderer auf Github</title>
		<link>http://www.pincservices.de/wordpress/java-groovy-sample-project-pdfrenderer-auf-github</link>
		<comments>http://www.pincservices.de/wordpress/java-groovy-sample-project-pdfrenderer-auf-github#comments</comments>
		<pubDate>Wed, 29 Dec 2010 18:46:13 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Projekte]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[html2pdf]]></category>
		<category><![CDATA[pdf]]></category>
		<category><![CDATA[pdfrenderer]]></category>
		<category><![CDATA[renderer]]></category>

		<guid isPermaLink="false">http://www.pincservices.de/wordpress/?p=545</guid>
		<description><![CDATA[Das Buch &#8220;Groovy in Action&#8221; führt den Begriff &#8220;Beauty through Brevity&#8221; ins Feld, der auch gern in Verbindung mit Scala oder Clojure einhergeht. Lässt man diese Sprachen für sich alleine mag das auch gelten, doch für viele Entwicklungen, die noch mit älterem Java-Code arbeiten, ist es wichtig, dass die Kombination verschiedener Sprachen ein stimmiges Gesamtbild [...]]]></description>
			<content:encoded><![CDATA[<p>Das Buch &#8220;Groovy in Action&#8221; führt den Begriff &#8220;Beauty through Brevity&#8221; ins Feld, der auch gern in Verbindung mit Scala oder Clojure einhergeht. Lässt man diese Sprachen für sich alleine mag das auch gelten, doch für viele Entwicklungen, die noch mit älterem Java-Code arbeiten, ist es wichtig, dass die Kombination verschiedener Sprachen ein stimmiges Gesamtbild abgibt &#8211; und hier lauern gern die ein oder anderen Stolperdrähte.</p>
<p>Unter <a href="https://github.com/Zigu/PdfRenderer">https://github.com/Zigu/PdfRenderer</a> habe ich ein älteres Projekt von mir in ein neues &#8220;Misch-Gewand&#8221; geworfen und geschaut ob es funktioniert. Und ja, das tut es &#8211; mit Einschränkungen.</p>
<p>Grundsätzlich kann man sagen, dass die Kombination Maven2 + Java + Groovy eine sehr angenehme Sache ist, wenngleich der Weg dorthin etwas dornig war. Insbesondere durch die maßlos veraltete Dokumentation von GMaven &#8211; ich verzichte bewusst auf eine Verlinkung &#8211; wodurch nicht klar war, wie einfach es eigentlich ist Maven dazu zu bringen auch Groovy-Code zu verarbeiten.</p>
<p>Vorsicht ist allerdings geboten beim Einsatz von Closures in Vererbungshierarchien. Es gibt in Groovy 1.7.6 noch ein Problem, wenn eine konkrete Kindklasse aufgerufen wird, deren abstrakte Oberklasse ein Closure enthält, dass private Felder dieser Elternklasse verwendet. Eine kurze Skizzierung des Problems:</p>
<pre class="brush: plain;">
abstract class A {
  private List _myList;
  private ListElementHandler _handler;

  public void handleList() {
    _myList.each{ _handler.do_something_with(it) }
  }
}

class B extends A { ... }

class C {
  public void call() {
    def b = new B()
    b.handleList()
  }
}
</pre>
<p>Leider kommt es im Zuge des Abarbeitung der Klasse C zu einer Exception, dass das Feld <code>_handler</code> nicht zur Klasse B gehört. Dieses Problem ist bereits in den Groovy-Bugtracker aufgenommen worden.</p>
<p>Trotz dieser kleineren Hürden, verlief die Umstrukturierung ziemlich glatt und am Ende entstand größtenteils ein stimmiges Gesamtbild mit einigen sehr angenehmen &#8220;Abkürzungen&#8221; dank Groovy.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pincservices.de/wordpress/java-groovy-sample-project-pdfrenderer-auf-github/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Erster Blick auf GWT 2.1.1 Requestfactory</title>
		<link>http://www.pincservices.de/wordpress/erster-blick-auf-gwt-2-1-1-requestfactory</link>
		<comments>http://www.pincservices.de/wordpress/erster-blick-auf-gwt-2-1-1-requestfactory#comments</comments>
		<pubDate>Thu, 16 Dec 2010 06:11:43 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Webentwicklung]]></category>
		<category><![CDATA[gwt]]></category>
		<category><![CDATA[RequestFactory]]></category>
		<category><![CDATA[servicelocator]]></category>

		<guid isPermaLink="false">http://www.pincservices.de/wordpress/?p=532</guid>
		<description><![CDATA[Vor einigen Tagen wurde der erste Release-Kandidat for GWT 2.1.1 veröffentlicht. Was dieser enthält kann man hier nachlesen. Nachdem ich bereits über einen Workaround für GWT 2.1 bezüglich des RequestFactory-Einsatzes mit Spring gesprochen habe war für mich vor allem das neue RequestFactory-API interessant. Dieses hat jetzt in u.a. in der Service-Annotation einen locator mit dem [...]]]></description>
			<content:encoded><![CDATA[<p>Vor einigen Tagen wurde der erste Release-Kandidat for GWT 2.1.1 veröffentlicht. Was dieser enthält kann man <a href="http://groups.google.com/group/google-web-toolkit/browse_thread/thread/6f2418947d7efeb9">hier</a> nachlesen.</p>
<p>Nachdem ich <a href="http://www.pincservices.de/wordpress/statische-schl…ory-mit-spring">bereits</a> über einen Workaround für GWT 2.1 bezüglich des RequestFactory-Einsatzes mit Spring gesprochen habe war für mich vor allem das neue RequestFactory-API interessant. Dieses hat jetzt in u.a. in der Service-Annotation einen <code>locator</code> mit dem man auf Klassen referenzieren kann, die keine statischen Methoden enthalten. Ein schönes Beispiel für den Einsatz findet sich in der GWT Google Group (<a href="https://groups.google.com/group/google-web-toolkit/browse_thread/thread/20ea2aea53aa29d3">zugehöriger Thread</a>).</p>
<p>Der folgende Auszug ist aus dem eben genannten Thread.</p>
<pre class="brush: java;">
public class SpringServiceLocator implements ServiceLocator {
        @Override
        public Object getInstance(Class&lt;?&gt; clazz) {
                HttpServletRequest request = RequestFactoryServlet.getThreadLocalRequest();
                ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(request.getSession().ge tServletContext());
                return context.getBean(clazz);
        }
}
</pre>
<p>&#8220;I annotate my RequestContext with the GWT @Service annotation (not the<br />
Spring one). Example below:&#8221;</p>
<pre class="brush: java;">
@Service(locator = SpringServiceLocator.class, value =
AddressService.class)
public interface AddressRequest extends RequestContext {
        // Get address by id
        Request&lt;AddressProxy&gt; get(Long id);
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.pincservices.de/wordpress/erster-blick-auf-gwt-2-1-1-requestfactory/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Clean Code und Refactoring &#8211; Das riecht aber komisch</title>
		<link>http://www.pincservices.de/wordpress/clean-code-und-refactoring-das-riecht-aber-komisch</link>
		<comments>http://www.pincservices.de/wordpress/clean-code-und-refactoring-das-riecht-aber-komisch#comments</comments>
		<pubDate>Tue, 07 Dec 2010 23:17:51 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Softwaredesign]]></category>
		<category><![CDATA[clean code]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[refactoring]]></category>

		<guid isPermaLink="false">http://www.pincservices.de/wordpress/?p=471</guid>
		<description><![CDATA[Wer sich schonmal über einen Quellcode gesetzt hat &#8211; über den eigenen oder eines anderen Entwicklers &#8211; und sich nach kurzer Zeit gefühlt hat, er müsse mal kurz weggehen um frische Luft zu bekommen, der hat es wohl mit einem sogenannten &#8220;Code smell&#8221; zu tun. &#8220;Code smell&#8221; ist ein Begriff, dem man &#8211; je länger [...]]]></description>
			<content:encoded><![CDATA[<p>Wer sich schonmal über einen Quellcode gesetzt hat &#8211; über den eigenen oder eines anderen Entwicklers &#8211; und sich nach kurzer Zeit gefühlt hat, er müsse mal kurz weggehen um frische Luft zu bekommen, der hat es wohl mit einem sogenannten &#8220;Code smell&#8221; zu tun. </p>
<p>&#8220;Code smell&#8221; ist ein Begriff, dem man &#8211; je länger man in der Softwareentwicklung unterwegs ist &#8211; mittlerweile kaum noch entgehen kann. Sei es nun im eigenen Projekt oder in der aktuellen Fachpresse. Für jene, denen dieser Begriff noch nicht geläufig ist, sei er wie folgt kurz erklärt:</p>
<p>Ein &#8220;Code smell&#8221; ist ein Symptom für tieferliegende Programm-Probleme, das sich durch unschönen bzw. verwirrenden Quellcode zeigt.</p>
<p>Eine konkretere Herleitung findet sich u.a. auf der entsprechenden <a href="http://en.wikipedia.org/wiki/Code_smell">Wikipedia-Seite</a>. Wie die obige Erklärung bereits andeutet sind Code smells eine relativ subjektive Angelegenheit. Wann ist eine Methode zu lang, oder was sind angemessene Variablenbezeichner? Eine Antwort auf diese Fragen muss man am Ende vor allem für sich selbst finden.<br />
Was ist jedoch zu tun, wenn man über solchen Code stolpert? Wie schreibe ich z.B. eine Methodensignatur so um, dass ich sicher sein kann, dass mein Code immer noch wie vorher funktioniert? Hierfür möchte ich 3 Bücher vorstellen, die man getrost als Leitfaden für Erkennung, Vermeidung und Aufräumaktionen verwenden kann.</p>
<div style="float:left; display: block; margin-bottom: 10px;">
<img class="wp-image-481" title="Clean Code" src="http://www.pincservices.de/wordpress/wp-content/uploads/2010/12/cc_bookReview_CleanCode.jpg" alt="" width="150" align="left" hspace="10"/> Clean Code stellt viele Aspekte für unschönen Code vor, die man bei der täglichen Arbeit zwar bemerkt, aber bei denen man unter Umständen nicht immer weiss wie man sie besser machen kann. Der Autor gibt sich hierbei nicht den Anspruch des allumfassenden &#8220;So-und-nicht-anders&#8221;, sondern lässt Freiraum für eigene Entscheidungen.
</div>
<div style="float:left; display: block; margin-bottom: 10px;">
<img class="wp-image-479" title="Refactoring" src="http://www.pincservices.de/wordpress/wp-content/uploads/2010/12/refactoring_book.png" alt="" width="150" align="left" hspace="10" /> Martin Fowler stellt verschiedene Refactoring-Mechanismen vor und erklärt die Motivation, die hinter jedem einzelnen steckt. Da es sich hierbei u.a. auch um sehr triviale Refactorings handelt, wirkt das Buch zeitweise etwas trocken.<br />
Dies wird jedoch durch die Darstellung verschiedener &#8220;Bad smells in Code&#8221; teilweise wieder ausgeglichen.
</div>
<div style="float: left; display: block;">
<img class="wp-image-480" title="Refactoring to Patterns" src="http://www.pincservices.de/wordpress/wp-content/uploads/2010/12/rtp.jpg" alt=""  width="150" align="left" hspace="10" /> Ähnlich aufgebaut wie das &#8220;Refactoring&#8221;-Buch werden hier verschiedene Code-Probleme anhand einfacher Beispiele erklärt und deren Lösung durch Patterns oder in Richtung eines Patterns vorgestellt.
</div>
<div style="clear:both;"></div>
<p>Wer sich etwas konkreter mit Refactoring an sich beschäftigten will, seien diese Bücher ans Herz gelegt. Wer meint, er schreibe bereits guten Code, möge folgenden Auszug aus &#8220;Clean Code&#8221; selbst prüfen: Guten Code erkennt man an der Metrik der WTF/minute eines Code Reviewers.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pincservices.de/wordpress/clean-code-und-refactoring-das-riecht-aber-komisch/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Statische Schleusen &#8211; GWT 2.1 RequestFactory mit Spring</title>
		<link>http://www.pincservices.de/wordpress/statische-schleusen-gwt-2-1-requestfactory-mit-spring</link>
		<comments>http://www.pincservices.de/wordpress/statische-schleusen-gwt-2-1-requestfactory-mit-spring#comments</comments>
		<pubDate>Fri, 26 Nov 2010 15:01:48 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Webentwicklung]]></category>
		<category><![CDATA[gwt]]></category>
		<category><![CDATA[RequestFactory]]></category>
		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://www.pincservices.de/wordpress/?p=456</guid>
		<description><![CDATA[Manchmal ist Vorfreude die schönste Freude, aber wenn die Vorfreude die einzige Freude ist, dann stimmt etwas nicht. So auch bei den heißersehnten RequestFactories von GWT 2.1. In Erwartung, dass damit der Zugriff auf Domain-Objekte/Entities stark vereinfacht werden soll, kam es &#8211; zumindest bei mir &#8211; zu einem jähen Erwachen, nachdem ich versuchte die RequestFactory [...]]]></description>
			<content:encoded><![CDATA[<p>Manchmal ist Vorfreude die schönste Freude, aber wenn die Vorfreude die einzige Freude ist, dann stimmt etwas nicht. So auch bei den heißersehnten RequestFactories von GWT 2.1. In Erwartung, dass damit der Zugriff auf Domain-Objekte/Entities stark vereinfacht werden soll, kam es &#8211; zumindest bei mir &#8211; zu einem jähen Erwachen, nachdem ich versuchte die RequestFactory auf ein Service-Klasse verweisen zu lassen, die von Spring verwaltet wird.</p>
<p>Die Entwickler der RequestFactory haben sich nämlich ein schönes Konstrukt in der Klasse <code>ReflectionBasedOperationRegistry</code> ausgedacht, welches es nur gestattet entweder statische Methode oder eine Methode der Entity selbst aufzurufen.</p>
<pre class="brush: java; wrap-lines: false;">
boolean isInstance = InstanceRequest.class.isAssignableFrom(requestMethod.getReturnType());
if (isInstance == Modifier.isStatic(domainMethod.getModifiers())) {
  throw new IllegalArgumentException(&quot;domain method &quot; + domainMethod
          + &quot; and interface method &quot; + requestMethod
          + &quot; don't match wrt instance/static&quot;);
}
</pre>
<p>Zur allgemeinen Verteidigung: in der kommenden Version GWT 2.1.1 wurde diese Einschränkung angeblich schon ausgebaut. Da zum aktuellen Zeitpunkt allerdings nicht klar ist, wann diese Version veröffentlicht wird, muss man sich mit anderen Mitteln behelfen. Eines dieser Mittel möchte ich kurz vorstellen.</p>
<p>Die Idee hinter dem ganzen ist es einen Adapter zu schreiben, der die notwendigen statischen Methoden für die RequestFactory bereitstellt und diese an den eigentlichen Service delegiert.<br />
Ich gehe davon aus, dass der Leser mit dem Grundprinzip der GWT RequestFactory vertraut ist. Falls nicht, empfehle ich einen Blick auf <a href="http://code.google.com/intl/de-DE/webtoolkit/doc/latest/DevGuideRequestFactory.html">diese Seite</a>.</p>
<p>Als Erstes möchte ich die RequestFactory vorstellen:</p>
<pre class="brush: java; wrap-lines: false;">
public interface SampleRequestFactory extends RequestFactory {

    @Service(SampleRequestAdapter.class)
    interface SampleRequestContext extends RequestContext {
        Request&lt;List&lt;SampleEntityProxy&gt;&gt; findAll();
    }

    SampleRequestContext sampleRequestContext();
}
</pre>
<p>Für diejenigen, die sich mit Spring auskennen sei darauf hingewiesen, dass die obige <code>Service</code>-Annotation nicht die von Spring, sondern die von GWT ist.</p>
<p>Weiter im Text &#8230;</p>
<p>Der entsprechende Adapter könnte in etwa so aussehen.</p>
<pre class="brush: java; wrap-lines: false;">
public class SampleRequestAdapter {

    private static SampleService _sampleService;

    public static void setApplicationContext(ApplicationContext applicationContext) {
        _sampleService = applicationContext.getBean(SampleService.class);
    }

    public static List&lt;SampleEntity&gt; findAll() {
        return _sampleService.findAll();
    }
}
</pre>
<p>Soweit, sogut. Bisher ist noch nichts Spannendes passiert. Dennoch ist die Luft bereits erfüllt mit &#8220;Entwickler-Magie&#8221;. Die offene Frage ist nämlich: Wie wird die Methode <code>setApplicationContext()</code> aufgerufen?</p>
<p>Die Lösung ist zwar nicht zwingend schön, aber wirkungsvoll:</p>
<ul>
<li>Man nehme eine Klasse, die von Spring verwaltet wird.</li>
<li>Mache diese Klasse <code>ApplicationContextAware</code>.</li>
<li>Gebe dieser Klasse die Adapter als Parameter und rufe für alle die Setter-Methode auf.</li>
</ul>
<p>Im Code-Gewand sähe dies so aus:</p>
<pre class="brush: java; wrap-lines: false;">
public class ApplicationContextProvider implements ApplicationContextAware {
    private List&lt;Class&gt; _requestAdapters;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (_requestAdapters != null) {
            for (Class requestAdapter : _requestAdapters) {
                try {
                    final Method setter = requestAdapter.getDeclaredMethod(&quot;setApplicationContext&quot;, ApplicationContext.class);
                    if (Modifier.isStatic(setter.getModifiers())) {
                        setter.invoke(requestAdapter, applicationContext);
                    }
                // ... exception handling code
            }
        }
    }

    public List&lt;Class&gt; getRequestAdapters() {
        return _requestAdapters;
    }

    public void setRequestAdapters(List&lt;Class&gt; requestAdapters) {
        _requestAdapters = requestAdapters;
    }
}
</pre>
<p>Abschließend muss der Provider selbstverständlich noch für Spring verfügbar gemacht werden.</p>
<pre class="brush: xml;">
&lt;bean class=&quot;de.sampleproject.ApplicationContextProvider&quot;&gt;
  &lt;property name=&quot;requestAdapters&quot;&gt;
    &lt;list&gt;
      &lt;value&gt;de.sampleproject.SampleRequestAdapter&lt;/value&gt;
    &lt;/list&gt;
  &lt;/property&gt;
&lt;/bean&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.pincservices.de/wordpress/statische-schleusen-gwt-2-1-requestfactory-mit-spring/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Joda &#8211; &#8220;Bis 900 Jahre, wirst aussehen du nicht gut!&#8221;</title>
		<link>http://www.pincservices.de/wordpress/joda-bis-900-jahre-wirst-aussehen-du-nicht-gut</link>
		<comments>http://www.pincservices.de/wordpress/joda-bis-900-jahre-wirst-aussehen-du-nicht-gut#comments</comments>
		<pubDate>Tue, 15 Dec 2009 09:45:34 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[date api]]></category>
		<category><![CDATA[joda]]></category>

		<guid isPermaLink="false">http://www.pincservices.de/wordpress/?p=370</guid>
		<description><![CDATA[Mit diesen Worten hat Yoda in Starwars nicht nur eine der traurigsten Szenen aufgelockert, sondern auch gleich &#8211; unbeabsichtigt &#8211; ein Grundproblem der Javawelt adressiert. Die API für die Zeitverwaltung. Wann wenn nicht jetzt? Beim Stöbern in Quellcode bin ich letztens wiedermal über eine lustige Zeile gestoßen: ... System.currentTimeInMillis() //we can get the time in [...]]]></description>
			<content:encoded><![CDATA[<p>Mit diesen Worten hat Yoda in Starwars nicht nur eine der traurigsten Szenen aufgelockert, sondern auch gleich &#8211; unbeabsichtigt &#8211; ein Grundproblem der Javawelt adressiert. Die API für die Zeitverwaltung.</p>
<h3>Wann wenn nicht jetzt?</h3>
<p>Beim Stöbern in Quellcode bin ich letztens wiedermal über eine lustige Zeile gestoßen:</p>
<pre class="brush: plain;">
...
System.currentTimeInMillis() //we can get the time in milliseconds after 1 Jan 1970 at 0:00:00am GMT
...
</pre>
<p>Auf den ersten Blick harmlos. Was soll da schon passieren? Ich will die Frage umformulieren: Was passiert danach? Mit dem Wert wird in der Regel angefangen zu arbeiten. D.h. Tage werden hinzugefügt, abgezogen um z.B. Startzeitpunkte zu ermitteln. Dabei wurde in dem Code, den ich gesehen habe in etwa folgendes gemacht:</p>
<pre class="brush: plain;">
final long now = System.currentTimeInMillis();
final long oneDay = 1000 * 60 * 60 * 24;
final long tomorrow = now + oneDay;
...
</pre>
<p>Sieht immer noch alles harmlos aus? Dann weiter &#8230;</p>
<h3>Ein Tag hat 24 Stunden</h3>
<p>An einer anderen Stelle wurde ein Vergleich zweier Daten durchgeführt. Hier die anonymisierte Fassung:</p>
<pre class="brush: plain;">
final long oneDay = 1000 * 60 * 60 * 24;

final Calendar calendar = Calendar.getInstance();
calendar.set(2009, 9, 24, 10, 0);
final long summerTime = calendar.getTimeInMillis();

final Calendar comparisonCalendar = Calendar.getInstance();
comparisonCalendar.set(2009, 9, 26, 10, 0);
final long winterTime = comparisonCalendar.getTimeInMillis();

final long difference = winterTime - summerTime;

if (difference == 2 * oneDay) {
    ...
}
</pre>
<p>Immer noch harmlos? Der ein oder andere wird jetzt sagen: klar. Leider steckt der Teufel im Detail. Was meistens vernachlässigt wird ist die europäische (Un)Sitte zwischen Sommer- und Winterzeit zu wechseln oder auch ganz allgemein alle 4 Jahre mal einen Tag im Februar mehr einzuplanen. Hier muss sich dieser Ansatz leider geschlagen geben.</p>
<p>Ich muss mich an dieser Stelle entschuldigen, denn ich habe den Code bereits so abgeändert, dass das Problem der Sommer- und Winterzeit offensichtlich wird. Der Originalcode sieht natürlich etwas anders aus. Aber nun sollte definitiv ersichtlich werden, warum das nicht funktionieren kann. Hier wird mit festen Zeitintervallen (<code>oneDay</code>) gearbeitet. Leider hat der Tag zum Zeitwechsel nicht 24, sondern entweder 23 oder 25 Stunden.</p>
<p>Geht man mit Java-Hausmitteln an dieses Problem landet man dann aber auch schnell in Code-Schnippseln wie dem Folgenden:</p>
<pre class="brush: plain;">
...
Calendar calendar = Calendar.getInstance();
Date now = calendar.getTime();
calendar.add(Calendar.HOUR_OF_DAY, 1);

...
</pre>
<p>oder die Alternative für den Vergleichscode:</p>
<pre class="brush: plain;">
...
Calendar calendar = Calendar.getInstance();
calendar.setTime(2009, 9, 24, 10, 0);
calendar.add(Calendar.HOUR_OF_DAY, 2);

Calendar comparisonCalendar = Calendar.getInstance();
comparisonCalendar.setTime(2009, 9, 26, 10, 0);
if (calendar.getTimeInMillis() == comparisonCalendar.getTimeInMillis()) {
...
</pre>
<p>Damit löst man zwar das Problem mit der Zeitumstellung, aber auf Dauer ist schön was anderes, denn ein weiterer Schwachpunkt der API, aus meiner Sicht, ist die schlechte Lesbarkeit. Denn wer sieht schon auf den ersten Blick, dass hier nicht der September, sondern der Oktober gemeint ist. Ja, man kann auch mit den <code>Calendar</code>-Konstanten arbeiten, aber auch das führt eher zu unnötig langen Codezeilen.</p>
<h3>&#8230; einer, der der Macht das Gleichgewicht bringen wird &#8230;</h3>
<p>Eine elegante Lösung hierfür bietet &#8211; nein nicht Skywalker, sondern &#8211; die <a href="http://joda-time.sourceforge.net/">Joda-Bibliothek</a>. Diese erlaubt es das Millisecond-Massaker zu umgehen und die Schwächen der Standard-API zu minimieren. So sieht der Code von oben mit Joda etwa so aus:</p>
<pre class="brush: plain;">
...
DateTime dt = new DateTime();
DateTime oneDayLater = dt.plusDays(1);
DateTime oneDayEarlier = dt.minusDays(1);
...
</pre>
<p>Auch Vergleiche wirken wesentlich angenehmer:</p>
<pre class="brush: plain;">
final DateTime now = new DateTime();
final DateTime before = now.minusDays(100);
final Days days = Days.daysBetween(before, now);
if (days.getDays() == 2) {
...
</pre>
<h3>&#8220;Schneller, leichter, verführerischer&#8221;</h3>
<p>Auch wenn das nur ein erster Blick auf Joda war, zeigt sich hier schon die Eleganz und Mächtigkeit dieser Bibliothek. Wer sich nicht scheut ein wenig englisch zu lesen, sei für weitere Informationen auf das IBM-Tutorial <a href="http://www.ibm.com/developerworks/java/library/j-jodatime.html" target="_blank">Joda-Time</a> und die Website <a href="http://joda-time.sourceforge.net" target="_blank">http://joda-time.sourceforge.net</a> selbst verwiesen.</p>
<p>Ansonsten, sehen wir uns in 900 Jahren um Mitternacht <img src='http://www.pincservices.de/wordpress/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<pre class="brush: plain;">
final LocalDate localDate = new LocalDate();
final DateTime then = localDate.toDateMidnight().toDateTime().plusYears(900);
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.pincservices.de/wordpress/joda-bis-900-jahre-wirst-aussehen-du-nicht-gut/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Und plötzlich war alles dunkel &#8230;</title>
		<link>http://www.pincservices.de/wordpress/und-plotzlich-war-alles-dunkel</link>
		<comments>http://www.pincservices.de/wordpress/und-plotzlich-war-alles-dunkel#comments</comments>
		<pubDate>Sat, 14 Nov 2009 09:40:03 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Projektverwaltung]]></category>
		<category><![CDATA[Werkzeuge]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[Genshi]]></category>
		<category><![CDATA[gtk+]]></category>
		<category><![CDATA[Trac]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.pincservices.de/wordpress/?p=343</guid>
		<description><![CDATA[Ich weiss nicht, was passiert ist, aber nach dem Upgrade von Ubuntu auf 9.10 wurden diverse Entwickler-Tools unbenutzbar. Dabei handelt es sich insbesondere um Anwendungen, die nicht direkt aus dem Ubuntu-Repository stammen. Im Folgenden will ich auf Eclipse und Trac eingehen. Eclipse 3.5 Nachdem auf GTK+ 2.18 aktualisiert wurde, funktionieren diverse Buttons in Eclipse nicht [...]]]></description>
			<content:encoded><![CDATA[<p>Ich weiss nicht, was passiert ist, aber nach dem Upgrade von Ubuntu auf 9.10 wurden diverse Entwickler-Tools unbenutzbar. Dabei handelt es sich insbesondere um Anwendungen, die nicht direkt aus dem Ubuntu-Repository stammen. Im Folgenden will ich auf Eclipse und Trac eingehen.</p>
<h3>Eclipse 3.5</h3>
<p>Nachdem auf GTK+ 2.18 aktualisiert wurde, funktionieren diverse Buttons in Eclipse nicht mehr. Schnell wird man dank Google auf der Suche nach einem Fix bzw. Workaround fündig (<a href="http://library.gnome.org/devel/gtk/2.18/gtk-migrating-ClientSideWindows.html">Migrating to client-side windows</a>). Offensichtlich ist die Umgebungsvariable <code>GDK_NATIVE_WINDOWS</code> für das Problem verantwortlich. Diese muss auf den Wert <code>true</code> gesetzt werden, damit SWT-basierte Java-Oberflächen (Anmerkung: auch andere Java-Applikationen mit SWT haben das Problem) wieder in altem Glanz erstrahlen.</p>
<pre class="brush: bash;">
#!/bin/bash
env GDK_NATIVE_WINDOWS=true &lt;your/eclipse/path&gt;/eclipse
</pre>
<p><em>(Den Pfad <code>&lt;your/eclipse/path&gt;</code> bitte an das jeweilige Installationsverzeichnis von Eclipse anpassen.)</em></p>
<p>Leider ist dies nur ein bescheidener Workaround, denn sobald man Eclipse aus sich heraus neu startet (z.B. nach Upgrades oder Plugin-Installationen) existiert das alte Problem wieder. Genauso, wenn man den Workspace versucht zu wechseln, da sich Eclipse auch hier herunterfährt und neu startet.</p>
<p>Ein richtiger Fix ist für die Version 3.5.2 angedacht bzw. soll in der 3.6 schon integriert sein, welche für die SDK-Variante bereits existiert. Nur für JEE-Developer wird es wohl noch etwas dauern.</p>
<p>Von einem globalen Umsetzen der Variable <code>GDK_NATIVE_WINDOWS</code> wird an diversen Stellen explizit abgeraten. Hier sei aber anzumerken, dass die Eclipse-Installation aus den Ubuntu-Repositories genau das macht. Für alle, die etwas &#8220;wagemutiger&#8221; sind hier das Startskript mit <code>export</code>.</p>
<pre class="brush: bash;">
#!/bin/sh

# work around e#290395 / LP: #458703
export GDK_NATIVE_WINDOWS=true

xuldir=/usr/lib/xulrunner-$(/usr/bin/xulrunner-1.9.1 --gre-version)
LD_LIBRARY_PATH=$xuldir${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} &lt;your/eclipse/path&gt;/eclipse
 &quot;$@&quot;
</pre>
<p><em>(Den Pfad <code>&lt;your/eclipse/path&gt;</code> bitte an das jeweilige Installationsverzeichnis von Eclipse anpassen.)</em></p>
<p>Dieses Skript am besten unter <code>/usr/local/bin</code> als <code>eclipse</code> ablegen und alle Links, die vorher direkt auf die Eclipse-Startdatei gegangen sind auf dieses Skript umbiegen.</p>
<h3>Trac</h3>
<p>Interessanterweise &#8211; was die primäre Motivation für diesen Kurzkommentar war &#8211; hat es auch das Bugtracking-Tool Trac erwischt. Zum Glück nicht so &#8220;heftig&#8221; wie Eclipse, aber dafür umso unverständlicher. </p>
<p>Ich habe lokal Trac mittels <code>easy_install</code> installiert gehabt. Nach dem Upgrade auf Ubuntu 9.10 erhielt ich plötzlich auf allen Trac-Seiten einen 500-Fehler. Nach kurzem Suchen fand ich in der <code>error.log</code>-Datei von Apache (Pfad unter Ubuntu: <code>/var/log/apache2/error.log</code>) folgenden Eintrag:</p>
<pre class="brush: plain; light: true;">
... [error] [client 127.0.0.1] ImportError: No module named genshi, ...
</pre>
<p>Warum das Modul plötzlich nicht mehr vorhanden war kann ich zum aktuellen Zeitpunkt nicht erklären, aber das war noch nicht das Ende.</p>
<p>Just in dem Moment wo ich mit </p>
<pre class="brush: plain; light: true;">
sudo easy_install Genshi
</pre>
<p>das entsprechende Modul installieren wollte, quittierte mir Ubuntu die Nachricht, dass <code>easy_install</code> nicht existiert. Ein kurzer Blick in Synaptic unter <code>python-setuptools</code> bestätigte die Vermutung, dass das Paket nicht installiert war. Ich möchte an dieser Stelle nicht ausschließen, dass es beim Upgrade in der Liste der zu deinstallierenden Pakete dabei war, aber dennoch ärgerlich. Also war auch hier nachinstallieren angesagt. </p>
<p>Zum Glück fügte sich dann alles sehr schnell. Das Genshi-Modul installierte sich ohne Probleme.</p>
<p>Abschließend musste noch der Workaround für einen Bug (<a href="http://trac.edgewall.org/ticket/7526">http://trac.edgewall.org/ticket/7526</a>)  eingebaut werden. Einfach die <code>compat.py</code> im <code>functional/tests</code>-Ordner in <code>testcompat.py</code><br />
umbenennen und die <code>compat.pyc</code> in <code>compat.pyc.old</code> umbenennen oder gleich löschen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pincservices.de/wordpress/und-plotzlich-war-alles-dunkel/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Webapps become wicket &#8230;</title>
		<link>http://www.pincservices.de/wordpress/webapps-become-wicket</link>
		<comments>http://www.pincservices.de/wordpress/webapps-become-wicket#comments</comments>
		<pubDate>Sat, 26 Sep 2009 00:59:55 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Webentwicklung]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[wicket]]></category>

		<guid isPermaLink="false">http://www.pincservices.de/wordpress/?p=247</guid>
		<description><![CDATA[Im Allgemeinen sprießen Webframeworks wie Pilze aus dem Boden. Mal mehr und mal weniger erfolgreich. Allerdings haben die meisten immer den gleichen MVC-Ansatz. Daten werden im Model vorgehalten, der Controller kümmert sich um die Bereitstellung der Objekte und der Navigation und das View &#8220;holt&#8221; sich alles was es braucht aus dem Kontext. D.h. man hat [...]]]></description>
			<content:encoded><![CDATA[<p>Im Allgemeinen sprießen Webframeworks wie Pilze aus dem Boden. Mal mehr und mal weniger erfolgreich. Allerdings haben die meisten immer den gleichen MVC-Ansatz. Daten werden im Model vorgehalten, der Controller kümmert sich um die Bereitstellung der Objekte und der Navigation und das View &#8220;holt&#8221; sich alles was es braucht aus dem Kontext. D.h. man hat häufig eine Mischung aus HTML und einer expliziten Expression Language im View (z.B. JSTL).<br />
Der große Nachteil bei dieser Form von Aufteilung ist, dass man beim Testen häufig auf verschiedene Frameworks zurückgreifen muss um die Korrektheit der Anzeige zu gewährleisten bzw. stark auf manuelles Testen angewiesen ist. Im Speziellen sei hier die Problematik von Text-Lokalisierung erwähnt, die jedem Entwickler im Laufe seiner Arbeit schonmal &#8220;auf die Füße gefallen&#8221; sein wird.</p>
<p>Einen etwas anderen Ansatz verfolgt an dieser Stelle das Framework <a href="http://wicket.apache.org">Wicket</a>. Hier wird bewusst auf eine explizite Expression Language verzichtet &#8211; soweit ich sehen kann. Alle Referenzen zwischen Controller und View werden über eine Wicket-Id-Tag (<code>&lt;span wicket:id="myMessage"&gt;&lt;/span&gt;</code>) aufgelöst. Damit steht zwar der Controller in der Pflicht alle Inhalte entsprechend umfangreicher aufzubereiten (z.B. explizite Änderungs-Propagierung), aber diese Vorgehensweise hat den elementaren Vorteil, dass Seiten wesentlich einfacher auch mit z.B. Junit-Tests geprüft werden können.</p>
<p>Es wäre alles zu schön um wahr zu sein, wenn es nicht schon auf den/meinen ersten Blick ein kleines Problem gäbe. Natürlich geht Wicket von einem MVC-Ansatz aus und benötigt damit HTML-Dateien zum Rendern. Leider wird standardmäßig davon ausgegangen, dass die HTML-Dateien im gleichen Verzeichnis liegen wie die entsprechende Klasse.<br />
<b-quote><i><br />
&#8220;First we need to create a web page. Wicket has a WebPage class suited for this task. All webpages need to be subclasses of WebPage. Another requirement is that the actual HTML file and the class name are equal: Index.html and Index, IndexPage.html and IndexPage or HelloWorld.html and HelloWorld. They also need to be in the same place on the classpath. The best way to develop is to put them in the same directory. This might seem strange in the beginning, especially when you are accustomed to separate html files and java files. However, since all pages are actually just components, it makes perfect sense in terms of reusability.&#8221;<br />
</i><br />
(siehe hierzu <a href="http://cwiki.apache.org/WICKET/newuserguide.html#Newuserguide-TheHTML">http://cwiki.apache.org/WICKET/newuserguide.html#Newuserguide-TheHTML</a>)<br />
</b-quote></p>
<p>Für jeden Webentwickler, der es gewohnt ist, dass HTML- respektive JSP(X)-Dateien gefälligst weit weg von den Klassen zu liegen haben, eine Umstellung die nur leidlich zu ertragen ist.<br />
Zum Glück haben die Wicket-Entwickler hier aber ein Einsehen und bieten in der Referenz-Dokumentation auch gleich mehrere <a href="http://cwiki.apache.org/WICKET/control-where-html-files-are-loaded-from.html">Lösungen</a> an, wobei aus meiner Sicht, die Maven-Lösung zu empfehlen ist, da sie versionsunabhängig ist.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pincservices.de/wordpress/webapps-become-wicket/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XML to the XStream</title>
		<link>http://www.pincservices.de/wordpress/xml-to-the-xstream</link>
		<comments>http://www.pincservices.de/wordpress/xml-to-the-xstream#comments</comments>
		<pubDate>Thu, 26 Mar 2009 06:57:49 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Werkzeuge]]></category>
		<category><![CDATA[Mapping]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[XStream]]></category>

		<guid isPermaLink="false">http://www.pincservices.de/wordpress/?p=170</guid>
		<description><![CDATA[Wer stand noch nicht vor dem Problem das &#8220;Allheilmittel&#8221;-Format XML parsen zu müssen? Allein das Implementieren des DOM-Parsers war immer schon ein Aufwand, der zumindest mich immer davon abgeschreckt hatte. Wenn das alleine aber schon nicht genug gewesen wäre, wollen die Werte ja auch weiterverarbeitet werden. D.h. es muss noch ein Mapper geschrieben werden. Aufwand [...]]]></description>
			<content:encoded><![CDATA[<p>Wer stand noch nicht vor dem Problem das &#8220;Allheilmittel&#8221;-Format XML parsen zu müssen?</p>
<p>Allein das Implementieren des DOM-Parsers war immer schon ein Aufwand, der zumindest mich immer davon abgeschreckt hatte. Wenn das alleine aber schon nicht genug gewesen wäre, wollen die Werte ja auch weiterverarbeitet werden. D.h. es muss noch ein Mapper geschrieben werden. Aufwand über Aufwand&#8230;</p>
<p>Doch wie so oft, ist ein &#8220;Retter in weißer Rüstung&#8221; zur Hilfe geeilt. Nachdem mehrere &#8220;Prinzen&#8221;, wie JAXB auf den Plan getreten sind, erschien letztens noch einer: <a href="http://xstream.codehaus.org/" target="_blank">XStream</a>. Eine Bibliothek mit der XML-Mapping in beide Richtungen mit wenigen Zeilen möglich ist. Insbesondere das Einlesen ist extrem einfach.</p>
<pre class="brush: xml;">
&lt;person&gt;
  &lt;firstname&gt;Joe&lt;/firstname&gt;
  &lt;lastname&gt;Walnes&lt;/lastname&gt;
  &lt;phone&gt;
    &lt;code&gt;123&lt;/code&gt;
    &lt;number&gt;1234-456&lt;/number&gt;
  &lt;/phone&gt;
  &lt;fax&gt;
    &lt;code&gt;123&lt;/code&gt;
    &lt;number&gt;9999-999&lt;/number&gt;
  &lt;/fax&gt;
&lt;/person&gt;
</pre>
<pre class="brush: java; toolbar: false;">
Person newJoe = (Person)xstream.fromXML(xml);
</pre>
<p>Und schon hat man sein Objekt. Hierbei sollte man jedoch Vorsicht walten lassen. Xstream ruft standardmäßig keinen Konstruktor auf. Das bedeutet, eigene Variablen, die nicht in der XML-Datei stehen werden gegebenenfalls nicht initialisiert. Wer darauf angewiesen ist, muss einen eigenen <a href="http://xstream.codehaus.org/converter-tutorial.html" target="_blank">Converter </a>registrieren.</p>
<p>Das Schreiben mit XStream ist ebenso einfach, wenngleich nicht so elegant. Vor allem bei Klassen, die viele Hilfsfelder haben, müssen diese mittels <code>omitField</code> von der Serialisierung ausgeklammert werden. Ein <code>transient</code> vor dem Attribut hilft da glücklicherweise. Es sei hier angemerkt, dass auf Feldebene gearbeitet wird. Man kann also keine Felder &#8220;verstecken&#8221;, da auch vor <code>private</code> nicht Halt gemacht wird.<br />
Hier wäre die Möglichkeit schön, alternativ alle Felder auszuschalten und nur explizit Felder freigeben zu können. Alternativ wäre interessant eher über die öffentlichen Zugriffsmethoden zu gehen.<br />
Ebenfalls ist noch keine Vererbungsprüfung möglich. D.h. wenn ich gleiche Felder in verschiedenen Subklassen existieren, muss jede Subklasse einzeln behandelt werden, was es insbesondere bei Plugin-Architekturen schwierig macht, da dort die Subklassen nicht immer bekannt sind.</p>
<p>Zusammenfassend würde ich sagen, dass XStream ein netter Anfang ist, aber noch einiges an Optimierungspotenzial enthält.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pincservices.de/wordpress/xml-to-the-xstream/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Craptecs: ICQ 4 MINA</title>
		<link>http://www.pincservices.de/wordpress/craptecs-icq-4-mina</link>
		<comments>http://www.pincservices.de/wordpress/craptecs-icq-4-mina#comments</comments>
		<pubDate>Thu, 12 Mar 2009 06:19:37 +0000</pubDate>
		<dc:creator>Rob</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Projekte]]></category>
		<category><![CDATA[crapchat]]></category>
		<category><![CDATA[craptecs]]></category>
		<category><![CDATA[ICQ]]></category>
		<category><![CDATA[MINA]]></category>

		<guid isPermaLink="false">http://www.pincservices.de/wordpress/?p=159</guid>
		<description><![CDATA[Apache MINA ist ein Framework für die Erstellung performanter und skalierbarer Netzwerkapplikationen. Eine Besonderheit dieses Frameworks ist, dass die API asynchron ist und weitestgehend unabhängig von spezifischen Protokollen. Im Rahmen eines Craptecs-Projektes soll im Laufe der nächsten Wochen eine Implementierung für das ICQ-Protokoll erstellt werden (siehe http://craptecs.blogspot.com/2009/03/proof-of-concept-icq-via-mina.html). Wer Interesse daran hat, kann sich gern bei [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://mina.apache.org/" target="_blank">Apache MINA</a> ist ein Framework für die Erstellung performanter und skalierbarer Netzwerkapplikationen. Eine Besonderheit dieses Frameworks ist, dass die API asynchron ist und weitestgehend unabhängig von spezifischen Protokollen.</p>
<p>Im Rahmen eines Craptecs-Projektes soll im Laufe der nächsten Wochen eine Implementierung für das ICQ-Protokoll erstellt werden (siehe <a href="http://craptecs.blogspot.com/2009/03/proof-of-concept-icq-via-mina.html" target="_blank">http://craptecs.blogspot.com/2009/03/proof-of-concept-icq-via-mina.html</a>).</p>
<p>Wer Interesse daran hat, kann sich gern bei mir <a href="http://www.pincservices.de/contact.php">persönlich</a> melden oder das craptecs-Team per IRC auf irc.freenode.org Kanal #craptecs aufsuchen. Wir würden uns freuen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pincservices.de/wordpress/craptecs-icq-4-mina/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

