<?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>IOException.de &#187; java</title>
	<atom:link href="http://www.ioexception.de/tag/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ioexception.de</link>
	<description>Ausgewählter Nerdkram von Informatikstudenten der Uni Ulm</description>
	<lastBuildDate>Fri, 13 Jan 2012 07:38:26 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Einfache Mobilapplikation mit Sensordaten und Real-Time-Streaming</title>
		<link>http://www.ioexception.de/2011/06/18/einfache-mobilapplikation-mit-sensordaten-und-real-time-streaming/</link>
		<comments>http://www.ioexception.de/2011/06/18/einfache-mobilapplikation-mit-sensordaten-und-real-time-streaming/#comments</comments>
		<pubDate>Sat, 18 Jun 2011 14:20:46 +0000</pubDate>
		<dc:creator>Benjamin Erb</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[ubiquitous computing]]></category>
		<category><![CDATA[uulm]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[location awareness]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[uni ulm]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.ioexception.de/?p=1030</guid>
		<description><![CDATA[Im Rahmen der Vorlesung &#8220;Mobile &#038; Ubiquitous Computing&#8221; (bin derzeit mitbetreuender Hiwi) waren wir auf der Suche nach passenden Übungsaufgaben. Eine Übung davon sollte verschiedene Aspekte aktueller Mobilapplikationen (Sensorkontext, Web Services, Live Notifications) einbeziehen, ohne dabei allzu komplex zu werden. 
Als ansatzweise reales Szenario hierfür dient die Mensa. Zu Stoßzeiten ist es häufig schwierig, in [...]]]></description>
			<content:encoded><![CDATA[<p>Im Rahmen der Vorlesung &#8220;Mobile &#038; Ubiquitous Computing&#8221; (bin derzeit mitbetreuender Hiwi) waren wir auf der Suche nach passenden Übungsaufgaben. Eine Übung davon sollte verschiedene Aspekte aktueller Mobilapplikationen (Sensorkontext, Web Services, Live Notifications) einbeziehen, ohne dabei allzu komplex zu werden. </p>
<p>Als ansatzweise reales Szenario hierfür dient die Mensa. Zu Stoßzeiten ist es häufig schwierig, in einer größeren Gruppe gemeinsam zu essen. Spätestens an den Kassen teilt sich die Gruppe auf und es ist schwierig, die Anderen zu finden. Ein Teil sitzt vielleicht auch schon an irgendeinem Tisch, während andere immer noch an der Essensausgabe warten. Was man also <em>unbedingt</em> braucht, ist ein Mensafinder. Der Mensafinder ermöglicht es, anderen seine grobe Position in der Mensa mitzuteilen oder aufzuzeigen, wo andere Leute sitzen. Aufgrund der Einschränkungen vor Ort (kein GPS-Empfang, WLan-Ortung zu ungenau) haben wir uns auf eine einzige Kontextinformationen beschränkt, die bereits eine ausreichende Lösung bietet – die Kompassausrichtung. Anstatt die genaue Position zu ermitteln, verwenden wir eine grobe Richtung abhängig von einem Fixpunkt im Zentrum des Raums (Wendeltreppe). Bereits sitzende Personen richten ihr Mobilgerät in Richtung des Fixpunktes aus, suchende Personen können ausgehend vom Fixpunkt den Richtungen folgen.</p>
<p><a href="http://www.ioexception.de/wp-content/uploads/2011/06/mensafinder.png"><img src="http://www.ioexception.de/wp-content/uploads/2011/06/mensafinder.png" alt="" title="mensafinder" width="600" height="338" class="alignnone size-full wp-image-1045" /></a></p>
<p>Technisch besteht der Mensafinder aus einem Webservice und mobilen Anwendungen. Der Webservice basiert auf REST und bietet als besonderes Feature das &#8216;Streamen&#8217; neuer Events (neue/aktualisierte Peilungen oder Abmeldungen). Hierfür wird durch den Client eine HTTP-Verbindung geöffnet und serverseitig nicht direkt geschlossen. Stattdessen werden neue Events via Chunked Encoding in die offene Verbindung geschrieben, ähnlich wie bei Streaming API von Twitter. Der Service wurde mit node.js implementiert, <a href="https://github.com/berb/mensafinder/tree/master/service">Quellcode</a> sowie <a href="https://github.com/berb/mensafinder/tree/master/api">Dokumentation der REST API</a> sind auf <a href="https://github.com/berb/mensafinder">github</a> verfügbar. </p>
<p>Da es sich nur um eine Demo-Applikation handelt, fehlen einige wichtige Features. Es gibt keine Authentisierung der Benutzer und es werden alle Peilungen aller Benutzer übertragen (es gibt keine Kontaktlisten). Interessant wäre natürlich die Anbindung an bestehende Dienste, die bereits eine Authentisierung und Kontaktlisten bereitstellen, so wie beispielsweise <a href="http://developers.facebook.com/blog/post/108/">Facebook Connect</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ioexception.de/2011/06/18/einfache-mobilapplikation-mit-sensordaten-und-real-time-streaming/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>GUIs &amp; Threads in Java ME</title>
		<link>http://www.ioexception.de/2011/04/05/guis-threads-in-java-me/</link>
		<comments>http://www.ioexception.de/2011/04/05/guis-threads-in-java-me/#comments</comments>
		<pubDate>Tue, 05 Apr 2011 11:25:29 +0000</pubDate>
		<dc:creator>Benjamin Erb</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[java me]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.ioexception.de/?p=954</guid>
		<description><![CDATA[Obwohl moderne Plattformen wie Android und iOS als auch alternative Ansätze wie mobile Webanwendungen zunehmend den Markt mobiler Applikationen beherrschen, spielt auch nach über 10 Jahren Java ME noch eine Rolle in diesem Bereich. Vor allem für Nicht-Smartphones und Low-End-Geräte ist Java ME eine verbreitete Technologie. Dieser Beitrag soll erläutern, wie man mit Java ME [...]]]></description>
			<content:encoded><![CDATA[<p>Obwohl moderne Plattformen wie Android und iOS als auch alternative Ansätze wie mobile Webanwendungen zunehmend den Markt mobiler Applikationen beherrschen, spielt auch nach über 10 Jahren Java ME noch eine Rolle in diesem Bereich. Vor allem für Nicht-Smartphones und Low-End-Geräte ist Java ME eine verbreitete Technologie. Dieser Beitrag soll erläutern, wie man mit Java ME Anwendungen implementieren kann, die aufwendige oder länger dauernde Operationen im Hintergrund ausführen und somit eine &#8220;responsive&#8221; GUI bereitstellen.</p>
<p>Bei interaktiven Anwendungen, die Inhalte aus dem Internet laden oder komplexe Berechnungen durchführen, ist es besonders wichtig, die Benutzerschnittstelle durch diese Aktionen nicht vollständig zu blockieren. So können zum Beispiel HTTP Requests in mobilen Netzwerken mehrere Sekunden benötigen – die Anwendung sollte trotzdem benutzbar bleiben oder zumindest dem Anwender über den Ladevorgang informieren.</p>
<p>Wie auch bei Desktop-Applikationen liegt hierbei der Schlüssel im Umgang mit Nebenläufigkeit. So wie es in gewöhnlichen Java-Anwendungen mit GUI einen AWT-Thread gibt, der mit einer Event-Queue auf GUI-Ereignisse wartet und diese verarbeitet, gibt es auch in Java ME ein ähnliches Konstrukt für die Benutzerschnittstelle. Wichtig ist es nun, länger dauernde Operationen nicht in dem jeweiligen Thread auszuführen, sondern in einem separaten Thread. So können auch weiterhin GUI-Ereignisse abgefangen werden, auch wenn die Operation noch andauert. Die eigentliche Aufgabe – I/O Operationen, Berechnungen etc. – wird in einem eigenen Thread oder einem Pool von Threads durchgeführt. Die Aktion wird aus dem GUI-Thread heraus gestartet (z.B. nach dem Click auf einem Button), allerdings eben nicht im GUI-Thread, sondern separat. Somit wird das Starten der Operation asynchron und somit nicht blockierend durchgeführt, und auch mit dem Resultat sollte ähnlich umgegangen werden. Das Ergebnis der Operation sendet nach Bearbeitung das Ergebnis wiederum an den GUI-Thread, der dies dann darstellt. Für den letzteren Fall gibt es bereits ein fertige Methode: <code>javax.microedition.lcdui.Display.callSerially(Runnable r)</code>. Diese Methode reiht das angegebene <code>Runnable</code> an das Ende der Event-Queue ein. Der GUI-Thread arbeitet wiederum die Events und <code>Runnables</code> der Reihe nach ab.</p>
<p>Für das Absenden von Hintergrundaktionen aus dem GUI-Thread bietet sich ein ähnliches Vorgehen an: Mithilfe einer blockierenden Queue sollten neue <code>Runnable</code>s angelegt und eingetragen werden. Ein Thread oder ein Pool von Threads sollte nun aus der Queue lesen und die dortigen <code>Runnable</code>s ausführen. Am Ende der <code>run()</code>-Methode jedes <code>Runnable</code>s  sollte nun das Resultat der Aufgabe wieder an die GUI zurückgegeben werden. Hierfür ist nun die <code>Display.callSerially(Runnable r)</code> hilfreich.</p>
<p>Die folgende Grafik illustriert das grundsätzliche Vorgehen:<br />
<a href="http://www.ioexception.de/wp-content/uploads/2011/04/eventqueue2.png"><img class="alignnone size-full wp-image-966" title="eventqueue" src="http://www.ioexception.de/wp-content/uploads/2011/04/eventqueue2.png" alt="" width="600" height="400" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ioexception.de/2011/04/05/guis-threads-in-java-me/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GoogleMap Vaadin Widget (Google Maps JavaScript API V3)</title>
		<link>http://www.ioexception.de/2010/10/08/googlemap-vaadin-widget/</link>
		<comments>http://www.ioexception.de/2010/10/08/googlemap-vaadin-widget/#comments</comments>
		<pubDate>Fri, 08 Oct 2010 14:59:04 +0000</pubDate>
		<dc:creator>Tobias Schlecht</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[google maps]]></category>
		<category><![CDATA[gwt]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[vaadin]]></category>

		<guid isPermaLink="false">http://www.ioexception.de/?p=628</guid>
		<description><![CDATA[Wer gerade dabei ist, eine Anwendung mit dem Web Application Framework Vaadin zu realisieren und darüber hinaus beabsichtigt, Google Maps in sein User Interface zu integrieren, hat mehrere Möglichkeiten.
Am naheliegendsten ist es zweifellos, einfach das fertige Vaadin Add-on GoogleMapWidget von Henri Muurimaa dafür zu nutzen, welches die Google Maps JavaScript API V2 einsetzt. Wenn man [...]]]></description>
			<content:encoded><![CDATA[<p>Wer gerade dabei ist, eine Anwendung mit dem Web Application Framework <a href="http://vaadin.com/">Vaadin</a> zu realisieren und darüber hinaus beabsichtigt, Google Maps in sein User Interface zu integrieren, hat mehrere Möglichkeiten.</p>
<p>Am naheliegendsten ist es zweifellos, einfach das fertige Vaadin Add-on <a href="http://vaadin.com/directory#addon/googlemapwidget">GoogleMapWidget</a> von Henri Muurimaa dafür zu nutzen, welches die <a href="http://code.google.com/intl/de-DE/apis/maps/documentation/javascript/v2/reference.html">Google Maps JavaScript API V2</a> einsetzt. Wenn man nun allerdings nicht nur die grundlegenden Funktionalitäten benötigt, kommt die Frage auf, ob man Anpassungen an diesem Widget vornehmen oder ein komplett neues Widget implementieren will.</p>
<p>Für den Fall, dass man sich dazu entschieden hat, ein eigenes Widget zu entwickeln, wäre es natürlich unsinnig, dafür noch die alte API Version und nicht die aktuelle Version, nämlich die <a href="http://code.google.com/intl/de-DE/apis/maps/documentation/javascript/reference.html">Google Maps JavaScript API V3</a>, zu verwenden.</p>
<div id="attachment_636" class="wp-caption alignright" style="width: 374px"><a href="http://www.ioexception.de/wp-content/uploads/2010/10/vaadin_googlemap.png"><img src="http://www.ioexception.de/wp-content/uploads/2010/10/vaadin_googlemap.png" alt="" title="Projektstruktur des Beispielprojekts IOException" width="364" height="528" class="size-full wp-image-636" /></a><p class="wp-caption-text">Projektstruktur des Beispielprojekts <strong><em>IOException</em></strong></p></div>
<p>Die meisten Entwickler möchten an dieser Stelle jedoch vermutlich kein JavaScript benutzen, da es ja einer der großen Vorteile von Vaadin ist, dass man die gesamte Anwendung in Java implementieren kann.</p>
<p>Also begibt man sich auf die Suche nach einer passenden GWT Library, welche Java Wrapper für die JavaScript API bereitstellt. Auf einer der <a href="http://code.google.com/p/gwt-google-apis/">offiziellen Seiten</a> über die GWT APIs wird man dann aber schnell durch folgende Aussage enttäuscht: &#8220;<em>At the present time, the gwt-maps API only supports Google Maps API version 2.</em>&#8221;</p>
<p>Jetzt hat man zwei Möglichkeiten: Entweder man wartet bis Google offiziell eine Library für die Version 3 zur Verfügung stellt, wozu es allerdings keine genauen Angaben gibt, wann das geschehen soll, oder aber man verwendet einfach die Alpha-Version der besagten GWT Library, die auf einer <a href="http://code.google.com/p/gwt-google-maps-v3/">inoffiziellen Seite</a> von Google zu finden ist.</p>
<p>Wer genug Zeit zum Warten und sich aus diesem Grund für die erste Möglichkeit ent- schlossen hat, braucht nun eigentlich nicht mehr weiterzulesen ;-) Allen Anderen soll nachstehend am Beispielprojekt <strong><em>IOException</em></strong> gezeigt werden, wie man das Grundgerüst für sein eigenes GoogleMap Vaadin Widget mit Hilfe der GWT Library <em>gwt-google-maps-v3</em> (Alpha-Version) erstellt.</p>
<p>Anmerkung: Im Folgenden werden lediglich die essenziellen Schritte aufgeführt. Für die Grundlagen zur Erstellung eines Vaadin Projekts wird auf das <a href="http://vaadin.com/book">Book of Vaadin</a> verwiesen, das vor allem für Anfänger sehr empfehlenswert ist.</p>
<p>Zuerst erzeugt man ein gewöhnliches Vaadin Projekt und legt daraufhin die im Screenshot dargestellte Projektstruktur an. Die JAR-Datei <em>gwt-maps3-0.2b.jar</em> (GWT Library) kann in der Rubrik <a href="http://code.google.com/p/gwt-google-maps-v3/downloads/list">Downloads</a> der bereits erwähnten inoffiziellen Seite von Google heruntergeladen werden.</p>
<p><strong>MANIFEST.MF</strong></p>
<pre class="brush: plain;">

Manifest-Version: 1.0
Vaadin-Widgetsets: de.ioexception.widgets.MainWidgetset.gwt.xml
</pre>
<p>In der Manifest-Datei muss durch das Attribut <code>Vaadin-Widgetsets</code> angegeben werden, wo sich der oberste GWT Modul Descriptor befindet, welcher das zentrale Widget Set definiert und auch als Einstiegspunkt zum Kompilieren dient.</p>
<p><strong>web.xml</strong> (Ausschnitt)</p>
<pre class="brush: xml;">

&lt;init-param&gt;
    &lt;param-name&gt;widgetset&lt;/param-name&gt;
    &lt;param-value&gt;de.ioexception.widgets.MainWidgetset&lt;/param-value&gt;
&lt;/init-param&gt;
</pre>
<p>Dies muss zusätzlich im Deployment Descriptor als <code>&lt;init-param&gt;</code> innerhalb der <code>&lt;servlet&gt;</code>-Tags aufgeführt werden.</p>
<p><strong>MainWidgetset.gwt.xml</strong> (Ausschnitt)</p>
<pre class="brush: xml;">

&lt;module&gt;
    &lt;inherits name=&quot;com.vaadin.terminal.gwt.DefaultWidgetSet&quot; /&gt;
    &lt;inherits name=&quot;de.ioexception.widgets.googlemap.GoogleMapWidgetset&quot; /&gt;
&lt;/module&gt;
</pre>
<p>Wie bereits erwähnt, wird in der Datei <em>MainWidgetset.gwt.xml</em> das zentrale Widget Set definiert. Dazu wird erst einmal vom Default Widget Set und anschließend von den GWT Modul Descriptoren der einzelnen Widget Sets geerbt. Da<br />
das gezeigte Beispielprojekt jedoch nur das GoogleMap Widget beinhaltet, ist dies hier auch die einzige Angabe.</p>
<p><strong>GoogleMapWidgetset.gwt.xml</strong> (Ausschnitt)</p>
<pre class="brush: xml;">

&lt;module&gt;
    &lt;inherits name=&quot;com.vaadin.terminal.gwt.DefaultWidgetSet&quot; /&gt;
    &lt;inherits name=&quot;com.google.gwt.maps.Maps&quot; /&gt;
    &lt;script src=&quot;http://maps.google.com/maps/api/js?sensor=false&quot; /&gt;
    &lt;source path=&quot;client&quot; /&gt;
&lt;/module&gt;
</pre>
<p>Um die JAR-Datei <em>gwt-maps3-0.2b.jar</em> (GWT Library) einzubeziehen, muss von deren GWT Modul Descriptor geerbt werden. Dies geschieht durch <code>&lt;inherits name="com.google.gwt.maps.Maps" /&gt;</code>. Durch den <code>&lt;script&gt;</code>-Tag erhält man Zugriff auf die Google Maps JavaScript API. Anschließend wird noch der Pfad, an dem sich die clientseitigen Dateien befinden, definiert.</p>
<p><strong>GoogleMap.java</strong></p>
<pre class="brush: java;">

package de.ioexception.widgets.googlemap.server;

import java.util.Map;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.ui.AbstractComponent;
import com.vaadin.ui.ClientWidget;
import de.ioexception.widgets.googlemap.client.VGoogleMap;

@ClientWidget(VGoogleMap.class)
public class GoogleMap extends AbstractComponent
{
    @Override
    public void paintContent(PaintTarget target) throws PaintException
    {
        super.paintContent(target);
    }

    @Override
    public void changeVariables(Object source, Map&lt;String, Object&gt; variables)
    {
        super.changeVariables(source, variables);
    }
}
</pre>
<p>Die Klasse <em>GoogleMap.java</em> ist an dieser Stelle nur der Vollständigkeit halber aufgeführt und bedarf eigentlich keiner weiteren Erklärung, da dies der gewöhnliche Aufbau einer serverseitigen Widget-Klasse ist und erst einmal nicht erweitert werden muss.</p>
<p><strong>VGoogleMap.java</strong></p>
<pre class="brush: java;">

package de.ioexception.widgets.googlemap.client;

import com.google.gwt.maps.client.base.LatLng;
import com.google.gwt.maps.client.MapOptions;
import com.google.gwt.maps.client.MapTypeId;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.SimplePanel;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.UIDL;

public class VGoogleMap extends Composite implements Paintable
{
    private SimplePanel wrapperPanel = null;
    private MapWidget mapWidget = null;
    private MapOptions mapOptions = null;

    public VGoogleMap()
    {
        wrapperPanel = new SimplePanel();

        initWidget(wrapperPanel);
    }

    @Override
    public void updateFromUIDL(UIDL uidl, ApplicationConnection client)
    {
        if(mapWidget == null)
        {
            initMap();
        }
    }

    private void initMap()
    {
        mapOptions = new MapOptions();

        mapOptions.setZoom(17);
        mapOptions.setCenter(new LatLng(48.42285529218286, 9.957287907600403));
        mapOptions.setMapTypeId(new MapTypeId().getSatellite());
        mapOptions.setScrollwheel(true);
        mapOptions.setDraggable(true);
        mapOptions.setNavigationControl(true);
        mapOptions.setMapTypeControl(true);

        mapWidget = new MapWidget(mapOptions);

        mapWidget.setWidth(&quot;800px&quot;);
        mapWidget.setHeight(&quot;500px&quot;);

        wrapperPanel.add(mapWidget);
    }
}
</pre>
<p>In der clientseitigen Widget-Klasse ist zu sehen, dass ein <code>MapWidget</code> nur mit <code>MapOptions</code> als Parameter initialisiert werden kann. Verpflichtend sind Werte zu den Eigenschaften <em>center</em>, <em>mapTypeId</em> und <em>zoom</em>. Im Absatz <a href="http://code.google.com/intl/de-DE/apis/maps/documentation/javascript/reference.html#MapOptions">MapOptions</a> der Google Maps JavaScript API V3 kann dies nachgelesen werden.</p>
<p><strong>IOException.java</strong></p>
<pre class="brush: java;">

package de.ioexception;

import com.vaadin.Application;
import com.vaadin.ui.Window;
import de.ioexception.widgets.googlemap.server.GoogleMap;

public class IOException extends Application
{
    @Override
    public void init()
    {
        Window mainWindow = new Window(&quot;IOException&quot;);
        GoogleMap googleMap = new GoogleMap();
        mainWindow.addComponent(googleMap);
        setMainWindow(mainWindow);
    }
}
</pre>
<p>Wie hier zu sehen ist, kann das GoogleMap Widget nun völlig unkompliziert verwendet werden. Als Beispiel dient dafür die Anwendungsklasse <code>IOException</code>, in der das initialisierte Widget einfach zum Main Window hinzugefügt wird.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ioexception.de/2010/10/08/googlemap-vaadin-widget/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ein PubSubHubbub-Subscriber-Client für Java</title>
		<link>http://www.ioexception.de/2010/08/14/pubsubhubbub-subscriber-java-client/</link>
		<comments>http://www.ioexception.de/2010/08/14/pubsubhubbub-subscriber-java-client/#comments</comments>
		<pubDate>Sat, 14 Aug 2010 21:02:18 +0000</pubDate>
		<dc:creator>Benjamin Erb</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[atom]]></category>
		<category><![CDATA[rss]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.ioexception.de/?p=606</guid>
		<description><![CDATA[Das Web ist mit HTTP fest an ein Client/Server-Modell gebunden und eine dadurch implizierte Asynchronität der Kommunikation. Requests können ausschließlich von Clients initiiert werden und immer von Servern in Form von Responses beantwortet. Ein solches Modell ist ausreichend für den Abruf von Informationen, setzt allerdings Schranken bezüglich anderer Interaktionsformen. Andere Protokolle wie XMPP, SIP oder [...]]]></description>
			<content:encoded><![CDATA[<p>Das Web ist mit HTTP fest an ein Client/Server-Modell gebunden und eine dadurch implizierte Asynchronität der Kommunikation. Requests können ausschließlich von Clients initiiert werden und immer von Servern in Form von Responses beantwortet. Ein solches Modell ist ausreichend für den Abruf von Informationen, setzt allerdings Schranken bezüglich anderer Interaktionsformen. Andere Protokolle wie XMPP, SIP oder auch Technologien wie nachrichtenbasierte Middlewaresysteme besitzen oft keine so deutliche Trennung zwischen Client/Server und erlauben weniger eingeschränkt die Kommunikation zwischen Knoten. Dadurch enstehen neben dem Request/Reply Muster weitere typischen Muster für den Austausch von Nachrichten. Ein Muster für die Benachrichtigung über Ereignisse ist das Publish/Subscribe Muster. Interessierte Knoten subskribieren sich für bestimmte Ereignisse und ereigniserzeugende Knoten publizieren diese. </p>
<p>Ein solches Kommunikationsmuster ist mit HTTP direkt nicht möglich, auch wenn es insbesondere für Feeds interessant wäre. Zwar bestehen mit Server Pushes / Long Polling oder dem aufkommenden WebSocket Standard vereinzelte Lösung für das prinzipielle Problem, dass HTTP keine serverinitiierte Kommunikation erlaubt, jedoch sind diese Insellösungen bisher kaum in der Breite verwendbar. </p>
<p>Google hat mit dem <a href="http://code.google.com/p/pubsubhubbub">PubSubHubbub</a>-Protokoll ein einfaches offenes Protokoll erschaffen, dass auf reinem HTTP basiert und ein solches Publish/Subscribe Muster unterstützt. Der Trick hierbei ist die Tatsache, dass alle beteiligten Knoten selbst sowohl Server wie auch Client sind und somit sowohl Requests empfangen wir auch versenden können. </p>
<p>Im Rahmen des diretto Projekts habe ich für unseren Client eine java-basierte Subscriber-Implementierung entwickelt. Als Feed kann jeder PubSubHubbub-fähige Atom-Feed benutzt werden. Im Falle einer Änderung des Feeds, zum Beispiel der Veröffentlichung eines neuen Eintrags, wird das &#8220;Delta&#8221; des Feeds, also der neue Teil an die Callback-Methode übergeben.</p>
<pre class="brush: java;">
Subscriber subscriber = new SubscriberImpl(&quot;subscriber-host&quot;,8888);
Subscription subscription = subscriber.subscribe(URI.create(&quot;http://feed-host/my-push-enabled-feed.xml&quot;));

subscription.setNotificationCallback(new NotificationCallback()
{

    @Override
    public void handle(SyndFeed feed)
    {
        //TODO: Do something more useful with the new entries
    	WireFeed inFeed = (WireFeed) feed.originalWireFeed();
    	if(inFeed instanceof Feed)
    	{
    		List&lt;?&gt; entries = ((Feed) inFeed).getEntries();
    		for (Object o : entries)
    		{
    			if(o instanceof Entry)
    			{
    				final Entry entry = (Entry) o;
    				System.out.println(&quot;New entry: &quot;+entry.getId());
    			}
    		}
    	}
    }

} );
</pre>
<p>Der Client benutzt intern <a href="http://rome.dev.java.net/">Rome</a> für die Auswertung der Atom-Feeds und <a href="http://www.eclipse.org/jetty/about.php">Jetty</a> als leichtgewichtigen, internen Webserver. Der Subscriber muss übrigens für den Hub erreichbar sein, insofern sollte er an eine öffentliche IP und den angegebenen Port gebunden werden.</p>
<p>Projekt auf github: <a href="http://github.com/berb/java-sub-pubsubhubbub">java-sub-pubsubhubbub</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ioexception.de/2010/08/14/pubsubhubbub-subscriber-java-client/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Atom Feeds in Java mit ROME direkt lesen</title>
		<link>http://www.ioexception.de/2010/06/13/atom-feeds-in-java-mit-rome-direkt-lesen/</link>
		<comments>http://www.ioexception.de/2010/06/13/atom-feeds-in-java-mit-rome-direkt-lesen/#comments</comments>
		<pubDate>Sun, 13 Jun 2010 10:18:47 +0000</pubDate>
		<dc:creator>Benjamin Erb</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[atom]]></category>
		<category><![CDATA[rss]]></category>

		<guid isPermaLink="false">http://www.ioexception.de/?p=577</guid>
		<description><![CDATA[Für die Interaktion mit Feeds gibt es in Java die weit verbreitete ROME-Library. Diese Library unterstützt sowohl RSS als auch ATOM in den verschiedenen Versionen. Außerdem bietet es eine Abstraktion an, die den Umgang mit den verschiedenen Feedarten vereinfachen soll. Ihre sogenannten Syndication Feeds bieten eine einheitliche Schnittstelle an, und sind unabhängig vom darunter liegenden [...]]]></description>
			<content:encoded><![CDATA[<p>Für die Interaktion mit Feeds gibt es in Java die weit verbreitete <a href="http://rome.dev.java.net/">ROME-Library</a>. Diese Library unterstützt sowohl <a href="http://de.wikipedia.org/wiki/RSS">RSS</a> als auch <a href="http://de.wikipedia.org/wiki/Atom_%28Format%29">ATOM</a> in den verschiedenen Versionen. Außerdem bietet es eine Abstraktion an, die den Umgang mit den verschiedenen Feedarten vereinfachen soll. Ihre sogenannten Syndication Feeds bieten eine einheitliche Schnittstelle an, und sind unabhängig vom darunter liegenden Format. Dies mag allgemein sehr hilfreich sein und für viele Fälle auch ausreichen. Typische Operationen sind somit entkoppelt vom Format und können wiederverwendet werden, oder das konkrete Format kann problemlos ausgetauscht werden.</p>
<p>Der Nachteil hierbei ist, dass bei dieser Abstraktion Besonderheiten der einzelnen Formate verborgen werden. Problematisch wird es zum Beispiel, wenn man explizit ein bestimmtes Format lesen möchte, um auf bestimmte Elemente zuzugreifen. So <a href="http://tools.ietf.org/html/rfc4287">muss in Atom</a> jeder Feed und Einträg ein ID Element besitzen, in RSS existiert dies jedoch nicht. Leider existiert nun auch keine Methode, ein solches Feld in einem Syndication Feed direkt abzufragen. </p>
<p>Nach einigem Suchen bin ich nun auf die Lösung gestoßen. Beim Einlesen des Feeds muss explizit ein Flag aktiviert werden, dass das zugrunde liegende Format ebenfalls mitgespeichert werden soll. Erst wenn <a href="http://rome.dev.java.net/apidocs/1_0/com/sun/syndication/io/SyndFeedInput.html#setPreserveWireFeed%28boolean%29">dieses Flag</a> gesetzt ist, lässt sich später der Feed im Originalformat (<a href="http://rome.dev.java.net/apidocs/1_0/com/sun/syndication/feed/WireFeed.html">WireFeed</a>) abrufen:</p>
<pre class="brush: java;">
InputSource source = new InputSource(...);
SyndFeedInput feedInput = new SyndFeedInput();
feedInput.setPreserveWireFeed(true);
SyndFeed feed = feedInput.build(source);
</pre>
<p>Später bietet dann der Syndication Feed Zugriff auf den  konkreten Feed:</p>
<pre class="brush: java;">
WireFeed wireFeed = (WireFeed) feed.originalWireFeed();
if(wireFeed instanceof com.sun.syndication.feed.atom.Feed)
{
   String feedId = ((Feed) wireFeed).getId()
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ioexception.de/2010/06/13/atom-feeds-in-java-mit-rome-direkt-lesen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>LRU-Cache in Java</title>
		<link>http://www.ioexception.de/2010/05/05/lru-cache-in-java/</link>
		<comments>http://www.ioexception.de/2010/05/05/lru-cache-in-java/#comments</comments>
		<pubDate>Wed, 05 May 2010 14:29:25 +0000</pubDate>
		<dc:creator>Benjamin Erb</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[datenstrukturen]]></category>

		<guid isPermaLink="false">http://www.ioexception.de/?p=520</guid>
		<description><![CDATA[Caches dienen in der Informatik als Methode, Zugriffe auf bestimmte Daten zu beschleunigen, in dem diese vorgelagert/gepuffert werden. Sie sind in verschiedensten Bereichen zu finden, unter anderem auf Prozessoren, in Festplatten, aber auch in Technologien wie dem Web. Verschiedene Verdrängungsstrategien ermöglichen es, die beschränkte Kapazität eines Caches zu berücksichtigen, so dass nur wichtige Werte im [...]]]></description>
			<content:encoded><![CDATA[<p>Caches dienen in der Informatik als Methode, Zugriffe auf bestimmte Daten zu beschleunigen, in dem diese vorgelagert/gepuffert werden. Sie sind in verschiedensten Bereichen zu finden, unter anderem auf Prozessoren, in Festplatten, aber auch in Technologien wie dem Web. Verschiedene Verdrängungsstrategien ermöglichen es, die beschränkte Kapazität eines Caches zu berücksichtigen, so dass nur wichtige Werte im Cache gelagert werden. Least Recently Used (LRU), ist eine solche Strategie, die häufig angewandt wird. Sie sortiert die Werte im Cache nach der letzten Nutzung. Wird auf ein Element über einen längeren Zeitraum nicht mehr zugegriffen, so wird es aus dem Cache verdrängt.</p>
<p>In Java lässt sich ein solcher LRU-Cache besonders einfach implementieren, da die <a href="http://java.sun.com/javase/6/docs/api/java/util/LinkedHashMap.html">Klasse</a> <code>java.util.LinkedHashMap</code> bereits die wesentlichen Mechanismen unterstützt. Eine <code>HashMap</code> ist eine Hash-Tabelle, die Zugriffe auf Werte über ihre Schlüssel regelt. Zusätzlich verkettet die <code>LinkedHashMap</code> aber die Werte noch in einer Liste, womit auch eine Traversierung in Einfügereihenfolge ermöglicht wird. Mithilfe eines Flags in einem der Konstruktoren kann dieses Verhalten geändert werden, so dass bei jedem Zugriff das angesprochene Element neu in diese Liste eingereiht wird. Damit verwaltet die Liste die Zugriffe und ist Basis für die LRU-Strategie.</p>
<p>Die Methode <code>removeEldestEntry()</code> der <code>LinkedHashMap</code> wird bei jedem Schreibezugriff auf die Map, also nach Einfügeoperationen über <code>put()</code> oder <code>putAll()</code> automatisch aufgerufen und bietet die Möglichkeit, durch Überschreiben der Methode die Verdrängungsstrategie zu implementieren. Diese Methode gibt ein <code>boolean</code> zurück, ob der älteste Eintrag gelöscht werden soll. Es ist auch möglich, innerhalb der Methode selbst die Liste zu manipulieren, dann sollte allerdings die Methode immer false zurückgeben. Für den LRU-Cache reicht es aus, die Größe der Map mit dem gewünschten Maximum zu vergleichen. Ist der Inhalt der Map zu groß, so soll das letzte Element gelöscht werden.</p>
<p>Im Folgenden nun der Code dazu. Zu beachten ist noch, dass es sich um eine threadsichere Klasse handelt, da die Map explizit synchronisiert wird. </p>
<pre class="brush: java;">
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * A thread-safe LRU cache implementation based on internal LinkedHashMap.
 *
 * @author Benjamin Erb
 *
 * @param &lt;K&gt; Entry Key Type
 * @param &lt;V&gt; Entry Value Type
 */
public class LRUCache&lt;K, V&gt;
{
	public static final int DEFAULT_MAX_SIZE = 1000;

	private final Map&lt;K, V&gt; internalMap;

	public LRUCache()
	{
		this(DEFAULT_MAX_SIZE);
	}

	public LRUCache(final int maxSize)
	{
		this.internalMap = (Map&lt;K, V&gt;) Collections.synchronizedMap(new LinkedHashMap&lt;K, V&gt;(maxSize + 1, .75F, true)
		{
			private static final long serialVersionUID = 5369285290965670135L;

			@Override
			protected boolean removeEldestEntry(Map.Entry&lt;K, V&gt; eldest)
			{
				return size() &gt; maxSize;
			}
		});
	}

	public V put(K key, V value)
	{
		return internalMap.put(key, value);
	}

	public V get(K key)
	{
		return internalMap.get(key);
	}

}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ioexception.de/2010/05/05/lru-cache-in-java/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mehrere Werte in Java-Methoden typsicher zurückgeben</title>
		<link>http://www.ioexception.de/2009/12/31/mehrere-werte-in-java-methoden-typsicher-zuruckgeben/</link>
		<comments>http://www.ioexception.de/2009/12/31/mehrere-werte-in-java-methoden-typsicher-zuruckgeben/#comments</comments>
		<pubDate>Thu, 31 Dec 2009 14:58:17 +0000</pubDate>
		<dc:creator>Benjamin Erb</dc:creator>
				<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://www.ioexception.de/?p=372</guid>
		<description><![CDATA[Anders als manch andere imperative Programmiersprachen, unterstützt Java nur die Rückgabe eines Wertes bei einem Methodenaufruf. Jedoch ist es häufig interessant, mehrere Werte zurückzugeben. Grundsätzlich lassen sich hier zwei Szenarien unterscheiden. Bei der Rückgabe von mehreren gleichartigen Typen wird meist eine Klasse des Collections-Frameworks verwendet, wie zum Beispiel List oder ein Array.  Manchmal will [...]]]></description>
			<content:encoded><![CDATA[<p>Anders als manch andere imperative Programmiersprachen, unterstützt Java nur die Rückgabe eines Wertes bei einem Methodenaufruf. Jedoch ist es häufig interessant, mehrere Werte zurückzugeben. Grundsätzlich lassen sich hier zwei Szenarien unterscheiden. Bei der Rückgabe von mehreren gleichartigen Typen wird meist eine Klasse des Collections-Frameworks verwendet, wie zum Beispiel List oder ein Array.  Manchmal will man aber auch völlig verschiedene Typen gemeinsam zurückgeben. Gängige Praxis ist es hier, ein Object-Array zurückzugeben und dann quasi beim Implementieren festzulegen, von welchem Typ die einzelnen Werte sind und entsprechen zurückzucasten. Dies ist leider weder typsicher, noch lässt sich die vorherige Festlegung im Code erzwingen. Abhilfe schafft hier eine generische Holder-Klasse, die einzelnen Werte typsicher kapselt und als einziger Rückgabewert verwendet werden kann.</p>
<p>Hier ein Beispiel für die Rückgabe über ein Object-Array:</p>
<pre class="brush: java;">
private Object[] doItUnchecked()
{
	String s = &quot;foo&quot;;
	Date d = new Date();

	return new Object[] { s, d };
}
</pre>
<p>Aufruf:</p>
<pre class="brush: java;">
// unchecked variant: dangerous!
Object[] returnValues = t.doItUnchecked();
String s = (String) returnValues[0];
Date d = (Date) returnValues[1];
</pre>
<p>Eine generische Holderklasse (hier:  <i>immutable</i>):</p>
<pre class="brush: java;">
/**
 * Immutable holder type for two values.
 *
 * @author Benjamin Erb
 *
 * @param &lt;F&gt; type of first value
 * @param &lt;S&gt; type of second value
 */
public class PairHolder&lt;F, S&gt;
{
	private final F first;
	private final S second;

	public PairHolder(F first, S second)
	{
		this.first = first;
		this.second = second;
	}

	public F getFirst()
	{
		return first;
	}

	public S getSecond()
	{
		return second;
	}
}
</pre>
<p>Verwendung in Methode:</p>
<pre class="brush: java;">
private PairHolder&lt;String, Date&gt; doItChecked()
{
	String s = &quot;foo&quot;;
	Date d = new Date();

	return new PairHolder&lt;String, Date&gt;(s, d);
}
</pre>
<p>Aufruf:</p>
<pre class="brush: java;">
// check variant: safe already at compile-time
PairHolder&lt;String, Date&gt; h = t.doItChecked();
String s = h.getFirst();
Date d = h.getSecond();
</pre>
<p>Die Holderklasse lässt sich auch noch beliebig erweitern, um Tripel, Quadrupel etc. zu halten. Wer für 2-Tupel keine eigene Klasse implementieren möchte, kann übrigens auf  <a href="http://java.sun.com/javase/6/docs/api/java/util/AbstractMap.SimpleEntry.html">AbstractMap.SimpleEntry<K,V></a> oder <a href="http://java.sun.com/javase/6/docs/api/java/util/AbstractMap.SimpleImmutableEntry.html">AbstractMap.SimpleImmutableEntry<K,V></a> zurückgreifen.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ioexception.de/2009/12/31/mehrere-werte-in-java-methoden-typsicher-zuruckgeben/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Typotisch</title>
		<link>http://www.ioexception.de/2009/09/18/typotisch/</link>
		<comments>http://www.ioexception.de/2009/09/18/typotisch/#comments</comments>
		<pubDate>Fri, 18 Sep 2009 15:08:20 +0000</pubDate>
		<dc:creator>David Langer</dc:creator>
				<category><![CDATA[visualisierungen]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[processing]]></category>
		<category><![CDATA[user interfaces]]></category>
		<category><![CDATA[visualisierung]]></category>

		<guid isPermaLink="false">http://www.ioexception.de/?p=306</guid>
		<description><![CDATA[
Typotisch – 1 from David L on Vimeo.
Dieses Projekt wurde im Rahmen des Praktikums &#8220;Aesthetic Computing&#8221; geplant und umgesetzt von Nora von Egloffstein und mir. Nachfolgend mehr Informationen (siehe auch hier).

Der Typotisch ist eine weiße Box, etwa so hoch wie eine Arbeitsplatte. Die  Oberseite  besteht aus einer Milchglasscheibe, auf  die der Benutzer [...]]]></description>
			<content:encoded><![CDATA[<p><object width="650" height="366"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=5199184&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=5199184&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="650" height="366"></embed></object>
<p><a href="http://vimeo.com/5199184">Typotisch – 1</a> from <a href="http://vimeo.com/user902215">David L</a> on <a href="http://vimeo.com">Vimeo</a>.</p>
<p>Dieses Projekt wurde im Rahmen des Praktikums &#8220;Aesthetic Computing&#8221; geplant und umgesetzt von Nora von Egloffstein und mir. Nachfolgend mehr Informationen (siehe auch <a href="http://kram.davidlanger.de/aec/">hier</a>).<br />
<span id="more-306"></span></p>
<p>Der Typotisch ist eine weiße Box, etwa so hoch wie eine Arbeitsplatte. Die  Oberseite  besteht aus einer Milchglasscheibe, auf  die der Benutzer Wortplättchen legen kann. Auf einer großen Leinwand oder einem Bildschirm wird dann eine Animation der  gelegten Worte gezeigt, wie wenn die Milchglasscheibe mit einer Kamera abgefahren würden. Je nachdem in welchem Winkel die Wortplättchen zueinander liegen, macht die Kamera eine entsprechende Drehung, auf 90° gerundet. Manche Wörter haben in der Animation einen fest  zugeordneten Effekt. Der Typotisch soll eine Verknüpfung von Kinetischer Typographie und einer besonderen Interaktionsmöglichkeit sein.</p>
<h2>Material</h2>
<p><img src="http://www.ioexception.de/wp-content/uploads/2009/09/typotisch2.jpeg" alt="typotisch2" title="typotisch2" width="200" height="112" class="alignright size-full wp-image-310" /> Die Box ist aus 12mm dicken MDF-Platten gebaut. Oben ist ein 30cm*30cm große Aussparung für die Milchglassplatte die dann auf Ausfräsungen am Rand der Aussparung gelegt werden kann. Im Inneren der Box sind zwei Bretter angebracht. </p>
<p>Die Wortplättchen sind aus Magnetgummi. Auf der vorderen Seite eines solchen Plättchens steht das Wort geschrieben und auf der Rückseite ist das Wort als QR-Code dargestellt. </p>
<h2>So funktioniert´s</h2>
<p><img src="http://www.ioexception.de/wp-content/uploads/2009/09/typotisch3.jpeg" alt="typotisch3" title="typotisch3" width="200" height="112" class="alignright size-full wp-image-311" /> Auf dem oberen inneren Brett wird eine Digitalkamera, bei uns eine Canon Powershot A620, mit Objektiv nach oben, angebracht. Auf dem unteren Brett steht ein mit der Kamera verbundener Laptop. Durch die Fernsteuerungssoftware von Canon wird alle zehn Sekunden ein Foto von der Milchglasscheibe gemacht und in einen Ordner abgelegt. Dieser Ordner ist für den zweiten Laptop im lokalen Netzwerk freigegeben. Die Software die auf diesem Laptop läuft, greift auf die Fotos zu und generiert die Animation. </p>
<h2>Software &#038; Libraries</h2>
<p><img src="http://www.ioexception.de/wp-content/uploads/2009/09/typotisch_qr.jpeg" alt="typotisch_qr" title="typotisch_qr" width="200" height="112" class="alignright size-full wp-image-308" /> Die Analyse des Fotos wurde mit Processing (<a class="footnote" href="#f1">1</a>) realisiert. Das Foto wird gelesen, potentielle Plättchen erkannt, dank einer Bibliothek für OpenCV für Processing (<a class="footnote" href="#f2">2</a>) Dann wird deren Lage bestimmt und  ihre Drehung auf 0°, 90°, 180° oder 270° gerundet. Anschließend wird die Reihenfolge der Plättchen ausgelesen, angefangen an der linken oberen Ecke der Milchglasscheibe. Dabei  werden auch die QR-Codes (<a class="footnote" href="#f3">3</a>) dekodiert. </p>
<ol>
<li id="f1"><a href="http://processing.org" />http://processing.org</a></li>
<li id="f2"><a href="http://ubaa.net/shared/processing/opencv/" />http://ubaa.net/shared/processing/opencv/</a></li>
<li id="f3"><a href="http://qrcode.sourceforge.jp/"  />http://qrcode.sourceforge.jp/</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.ioexception.de/2009/09/18/typotisch/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SequentialMessageQueues in Java</title>
		<link>http://www.ioexception.de/2009/08/14/sequentialmessagequeues-in-java/</link>
		<comments>http://www.ioexception.de/2009/08/14/sequentialmessagequeues-in-java/#comments</comments>
		<pubDate>Fri, 14 Aug 2009 13:01:48 +0000</pubDate>
		<dc:creator>Benjamin Erb</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[datenstrukturen]]></category>

		<guid isPermaLink="false">http://www.ioexception.de/?p=294</guid>
		<description><![CDATA[Viele Netzwerkprotokolle teilen ihre Kommunikationsentitäten in Pakete oder Nachrichten auf. Manche Protokolle erwarten außerdem eine sequentielle Abarbeitung (z.B. TCP auf Transportebene), auch wenn die darunterliegenden Protokollschichten dass nicht unbedingt unterstützen. Für die Implementierung eines Nachrichtenpuffers für RTSP-Nachrichten, die ungeordnet ankommen können, aber sequentiell abgearbeitet werden müssen, habe ich eine entsprechende Datenstruktur in Java erstellt. RTSP-Nachrichten [...]]]></description>
			<content:encoded><![CDATA[<p>Viele Netzwerkprotokolle teilen ihre Kommunikationsentitäten in Pakete oder Nachrichten auf. Manche Protokolle erwarten außerdem eine sequentielle Abarbeitung (z.B. TCP auf Transportebene), auch wenn die darunterliegenden Protokollschichten dass nicht unbedingt unterstützen. Für die Implementierung eines Nachrichtenpuffers für RTSP-Nachrichten, die ungeordnet ankommen können, aber sequentiell abgearbeitet werden müssen, habe ich eine entsprechende Datenstruktur in Java erstellt. RTSP-Nachrichten besitzen ein <code>Cseq</code>-Header-Feld, welches die einzelnen Nachrichten durchnummiert und als ordnendes Element genutzt werden kann.</p>
<p>Die folgende generische Implementierung erwartet, dass alle Nachrichtenelemete eindeutige und miteinander vergleichbare Identifier besitzen. Desweiteren erlaubt diese Implementierung zwar das parallele Schreiben in die Queue, allerdings sollte das Lesen durch einen einzelnen Thread realisiert werden. Ansonsten kann die Ordnung nach dem Entnehmen aus der Queue durch unterschiedlich lange Laufzeiten der Worker-Threads wieder verloren gehen. Außerdem realisiert diese Implementierung die sequentielle Ordnung eines vollständigen Nachrichtenstroms. Nachrichtenverluste oder Timeouts werden nicht behandelt. Hierfür eignen sich eher <a href="http://en.wikipedia.org/wiki/Automatic_repeat-request">Automatic repeat request Protokolle</a>.</p>
<p><strong>Interface für MessageQueue</strong><br />
Eine MessageQueue bietet die grundlegenden Funktionen zum Einfügen und Entfernen von Elementen sowie Hilfsmethoden für die Größe der Queue an.</p>
<pre class="brush: java;">
/**
 * Interface for message queues.
 *
 * @author Benjamin Erb
 *
 * @param &lt;E&gt;
 *            Element type
 */
public interface MessageQueue&lt;E&gt;
{
	/**
	 * Adds element to queue. Blocks until element can be added.
	 *
	 * @param e
	 *            new element
	 * @throws InterruptedException
	 */
	void push(E e) throws InterruptedException;

	/**
	 * Takes an element from the queue. Blocks until element becomes available.
	 *
	 * @return taken element
	 * @throws InterruptedException
	 */
	E pop() throws InterruptedException;

	/**
	 * Gets the size of the queue
	 *
	 * @return
	 */
	int size();

	/**
	 * Checks whether queue is empty or not.
	 *
	 * @return
	 */
	boolean empty();

}
</pre>
<p><strong>Interface für speziellen Comparator</strong><br />
Dieses spezielel Comparator-Interface fügt Methoden hinzu für das Erfragen von vorherigen und nachfolgenden Identifiern an. Außerdem können Nachrichten, Identifier oder eine Kombination aus beidem verglichen werden.</p>
<pre class="brush: java;">
import java.util.Comparator;

/**
 * An enhanced comparator interface for retrieving preceding and subsequent identifiers.
 *
 * @author Benjamin Erb
 *
 * @param &lt;E&gt; Element type
 * @param &lt;T&gt; Element identifier
 */
/**
 */
public interface SequentialComparator&lt;E, T extends Comparable&lt;T&gt;&gt; extends Comparator&lt;E&gt;
{
	/**
	 * Returns the subsequent identifier of a given entity.
	 *
	 * @param t
	 *            entity
	 * @return subsequent identifier
	 */
	T getNext(E e);

	/**
	 * Returns the preceding identifier of a given entity.
	 *
	 * @param t
	 *            entity
	 * @return preceding identifier
	 */
	T getPrevious(E e);

	/**
	 * Compares two entities.
	 *
	 * @param t1
	 *            entity 1
	 * @param t2
	 *            entity 2
	 * @return a negative integer, zero, or a positive integer as the first
	 *         argument is less than, equal to, or greater than the second.
	 */
	int compare(T t1, T t2);

	/**
	 * Compares an entity and an identifier.
	 *
	 * @param t1
	 *            entity
	 * @param e2
	 *            identifier
	 * @return a negative integer, zero, or a positive integer as the first
	 *         argument is less than, equal to, or greater than the second.
	 */
	int compare(T t1, E e2);

	/**
	 * Compares an identifier and an entity.
	 *
	 * @param e1
	 *            identifier
	 * @param t2
	 *            entity
	 * @return a negative integer, zero, or a positive integer as the first
	 *         argument is less than, equal to, or greater than the second.
	 */
	int compare(E e1, T t2);
}
</pre>
<p><strong>SequentialMessageQueue Implementierung</strong><br />
Die eigentliche Queue-Implementierung greift intern auf eine PriorityBlockingQueue zurück, allerdings wird durch die Kapselung sichergestellt, dass nur das nächste zu erwartende Element entnommen werden kann.</p>
<pre class="brush: java;">
import java.util.concurrent.PriorityBlockingQueue;

/**
 * A message queue for sequential message processing. This queue orders incoming
 * messages entities by their identifiers and outputs entites in-order. This
 * queue supports more than one writing thread. However, it is designed for one
 * reading/consuming thread in order to prevent out-of-order processing by
 * multiple threads.
 *
 * @author Benjamin Erb
 *
 * @param &lt;E&gt;
 *            Message entity
 * @param &lt;T&gt;
 *            Message identifier
 */
public class SequentialMessageQueue&lt;E, T extends Comparable&lt;T&gt;&gt; implements MessageQueue&lt;E&gt;
{
	/**
	 * Lock object for queueing
	 */
	private final Object lock = new Object();

	/**
	 * internal queue
	 */
	private final PriorityBlockingQueue&lt;E&gt; internalQueue;
	/**
	 * comparator
	 */
	private final SequentialComparator&lt;E, T&gt; comparator;

	/**
	 * Represents the identifier of the next expected entity
	 */
	private T expectedIdentifier;

	public SequentialMessageQueue(SequentialComparator&lt;E, T&gt; comparator, T initialIdentifier)
	{
		this.internalQueue = new PriorityBlockingQueue&lt;E&gt;(16, comparator);
		this.comparator = comparator;
		this.expectedIdentifier = initialIdentifier;
	}

	@Override
	public boolean empty()
	{
		return internalQueue.isEmpty();
	}

	@Override
	public E pop() throws InterruptedException
	{
		synchronized (lock)
		{
			E firstElement;
			while ((firstElement = internalQueue.peek()) == null || comparator.compare(firstElement, expectedIdentifier) != 0)
			{
				lock.wait();
			}
			internalQueue.remove();
			expectedIdentifier = comparator.getNext(firstElement);
			return firstElement;
		}
	}

	@Override
	public void push(E e) throws InterruptedException
	{
		synchronized (lock)
		{
			internalQueue.put(e);
			lock.notifyAll();
		}

	}

	@Override
	public int size()
	{
		return internalQueue.size();
	}

	/**
	 * Returns the used comparator
	 *
	 * @return
	 */
	protected SequentialComparator&lt;E, T&gt; getSequentialComparator()
	{
		return comparator;
	}

}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ioexception.de/2009/08/14/sequentialmessagequeues-in-java/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Schnelle Quellcode-Navigation in Eclipse</title>
		<link>http://www.ioexception.de/2009/08/11/schnelle-quellcode-navigation-in-eclipse/</link>
		<comments>http://www.ioexception.de/2009/08/11/schnelle-quellcode-navigation-in-eclipse/#comments</comments>
		<pubDate>Tue, 11 Aug 2009 14:27:52 +0000</pubDate>
		<dc:creator>Benjamin Erb</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[eclipse]]></category>

		<guid isPermaLink="false">http://www.ioexception.de/?p=284</guid>
		<description><![CDATA[Bei der Entwicklung größerer Java-Projekte kann schnell die Übersicht verloren gehen. Zum Glück bietet Eclipse eine Vielzahl von Shortcuts und Funktionen, um sich auch noch bei einer Vielzahl von Klassen zurecht zu finden. 

Strg + 3Öffnet den intelligenten Quick Access Dialog.
Strg + Shift + RÖffnet einen Schnelldialog zum Öffnen einer Ressource. Ist insbesondere hilfreich, um [...]]]></description>
			<content:encoded><![CDATA[<p>Bei der Entwicklung größerer Java-Projekte kann schnell die Übersicht verloren gehen. Zum Glück bietet Eclipse eine Vielzahl von Shortcuts und Funktionen, um sich auch noch bei einer Vielzahl von Klassen zurecht zu finden. </p>
<ul>
<li><code>Strg + 3</code><br/>Öffnet den intelligenten <em>Quick Access</em> Dialog.</li>
<li><code>Strg + Shift + R</code><br/>Öffnet einen Schnelldialog zum Öffnen einer Ressource. Ist insbesondere hilfreich, um eine Datei mit bekanntem Dateinamen direkt zu öffnen, ohne im Package Explorer zu suchen.
<li><code>Strg + Shift + T</code><br/>Öffnet einen Schnelldialog zum Öffnen einer Java-Ressource. In der Auswahl kann der Name der Klasse/Interface/etc. direkt eingegeben werden.
<li><code>Strg + <em>Linksklick auf Klassenname</em></code><br/>Sprung zum Quelltext der Klasse, auf die im Editor geklickt wird.
<li><code>Strg + T</code><br/>Übersicht der Vererbungshierarchie der Klasse, die sich im Fokus des Editors befindet. Nochmaliges Drücken von <code>Strg + T</code> dreht die Hierarchierichtung (Superklassen/Subklassen) um.
<li><code>Strg + O</code><br/>Übersicht der Membervariablen und Methoden der aktuellen Klasse. Nochmaliges Drücken von <code>Strg + O</code> zeigt zusätzlich geerbte Member an.
<li><code>Strg + Shift + G</code><br/>Sucht nach Verwendungen der Methode im Fokus des Editors in alles Klassen der Workspaces.
<li><code>Strg + .</code> und <code>Strg + '+'</code><br/>Sprung durch die Quelltextzeilen mit Warnungen</li>
<li><code>Strg + L</code><br/>Öffnet Dialog für einen Sprung in eine bestimmte Codezeile.
<li><code>Strg + E</code><br/>Zeigt Liste aller offenen Editors-Tabs an und ermöglicht Direktauswahl eines offenen Editorstabs per Texteingabe.
<li><code>Strg + Bild Auf</code> und <code>Strg + Bild Ab</code><br/>Springen durch die offenen Editor-Tabs.
<li><code>Alt + ←</code> und <code>Alt + →</code><br/>Springen durch die Historie der geöffneten Tabs.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.ioexception.de/2009/08/11/schnelle-quellcode-navigation-in-eclipse/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

