<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
   <channel>
      <title>Philipps paper equivalent Blog</title>
      <link>http://www.innoq.com/blog/phaus/</link>
      <description></description>
      <language>en</language>
      <copyright>Copyright 2008</copyright>
      <lastBuildDate>Fri, 11 Jul 2008 02:09:01 +0100</lastBuildDate>
      <generator>http://www.sixapart.com/movabletype/</generator>
      <docs>http://blogs.law.harvard.edu/tech/rss</docs> 

            <item>
         <title>subversion problem: svn: Can&apos;t move &apos;xyz/.svn/tmp/entries&apos; to &apos;xyz/.svn/entries&apos;: Operation not permitted</title>
         <description><![CDATA[<font size="2"><span style="font-style: italic;">    &nbsp;&nbsp;&nbsp; svn: Can't move 'xyz/.svn/tmp/entries' to 'xyz/.svn/entries': Operation not permitted</span></font>

Diese Fehler sprang mir grade entgegen, nachdem ich mal wieder ein <span style="font-style: italic;">svn up</span> machen wollte.
Nach genauerer Betrachtung, stellte ich dann fest, dass <span style="font-style: italic;">xyz/.svn/entries </span>nur Lesesrechte hat.

Ein 
<font size="2">&nbsp;&nbsp;&nbsp; sudo chmod 777 </font><span style="font-style: italic;"><font size="2">xyz/.svn/entries </font>
</span>half leider auch nichts:
<font size="2">&nbsp;&nbsp;&nbsp; chmod: ./<span style="font-style: italic;">xyz/.svn/entries</span>: Operation not permitted</font>

Das fand ich dann schon ziemlich dreist irgendwie :-D.
Letztendlich half mir ein:

<font size="2">
&nbsp;&nbsp;&nbsp;<span style="font-style: italic;"> cp xyz/.svn/entries </span><span style="font-style: italic;">xyz</span><span style="font-style: italic;">/.svn/entries2</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; sudo rm </span><span style="font-style: italic;">xyz</span><span style="font-style: italic;">/.svn/entries</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; cp </span><span style="font-style: italic;">xyz</span><span style="font-style: italic;">/.svn/entries2 </span><span style="font-style: italic;">xyz</span><span style="font-style: italic;">/.svn/entries</span><br style="font-style: italic;" /><span style="font-style: italic;"><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; sudo chmod 777&nbsp; </span></span><span style="font-style: italic;">xyz</span></font><span style="font-style: italic;"><span style="font-style: italic;"><font size="2">/.svn/entries</font>

</span></span>
Was zwar auf dem ersten Blick ein wenig aufwendig erscheint, aber in Form eines shell-scriptes angenehm die Arbeit übernimmt.
Allerdings weiß ich jetzt immer noch nicht WARUM dieser Fehler kommt.

Letztendlich habe ich mich ja daran gewöhnt, dass subversion meint, . hätte ein Lock....
Wenn mir da jemand mal erklären könnte, ob ich da was falsch mache oder wie... das fände ich mal toll :-).<span style="font-style: italic;"><span style="font-style: italic;">
</span>
</span>
  <div class="flockcredit" style="text-align: right; color: #CCC; font-size: x-small;">Blogged with the <a href="http://www.flock.com/blogged-with-flock" style="color: #999; font-weight: bold;" target="_new" title="Flock Browser">Flock Browser</a></div>]]></description>
         <link>http://www.innoq.com/blog/phaus/2008/07/subversion_problem_svn_cant_mo.html</link>
         <guid>http://www.innoq.com/blog/phaus/2008/07/subversion_problem_svn_cant_mo.html</guid>
        
        
         <pubDate>Fri, 11 Jul 2008 02:09:01 +0100</pubDate>
      </item>
            <item>
         <title>Multicast - genauer Nachgeschaut</title>
         <description><![CDATA[Da das ja heute bei der Tafelrunde eher etwas zusammengesucht war, habe ich mich noch mal hingesetzt und mir die Dinge an-/eingelesen.
Ich werde einfach mal versuchen die Fragen, die da aufkamen wiederzugeben und dann mit passenden Texten beantworten:


<ol><li>Was ist Multicast?
Multicast ist eine Nachrichtenübertragung von einem Punkt zu einer Gruppe von Empfängern (auch Mehrpunktverbindung genannt). 
Daneben gibt es noch weitere Arten von Übertragungen:
<ul><li>Unicast: eine Punkt-zu-Punkt-Verbindung (klassische Client&lt;-&gt;Server Verbindung)
 </li><li>Broadcast- und die Anycast-Übertragung ("ich bin da - wer noch?" - ping an x.x.x.255)
 </li><li>Geocast, ein besonderer Multicast, der räumlich begrenzt ist.

</li></ul></li><li>Was sind die Vorteile von Multicast gegenüber Unicast?
Es sind gleichzeitige Nachrichten an mehrere Teilnehmer möglich, ohne dass sich die Bandbreite des Senders verändert (für den Sender ist es als würde man eine Nachricht an einen Empfänger senden). 
Handelt es sich um paketorientierte Datenübertragung, findet die Vervielfältigung der Pakete an jedem Verteiler (Switch, Router) auf der Route statt.

</li><li>Wie geht das nun genau?
Multicast ist die übliche Bezeichnung für IP-Multicast, das es ermöglicht, in IP-Netzwerken effizient Daten an viele Empfänger zur gleichen Zeit zu senden. Das passiert mit einer speziellen Multicast-Adresse. In IPv4 ist hierfür der Adress-Bereich 224.0.0.0 bis 239.255.255.255 (Klasse D), in IPv6 jede mit FF00::/8 beginnende Adresse reserviert.
Bei der Übertragung über Ethernet werden die IPv4- bzw. IPv6-Multicastadressen auf bestimmte Pseudo-MAC-Adressen abgebildet, um bereits durch die Netzwerkkarte eine Filterung nach relevantem Traffic zu ermöglichen.

</li><li>Okaaaaay.... Wer macht sowas? Ist sowas nützlich?
Ja ist es. Bekannte Anwendungen sind:
<ul><li>Audio- und Videoübertragungen (Protokolle wie RTP)</li><li>Verwendung beim Clustering und beim Routing nach dem Routing Information Protocol (RIP) Version 2.</li><li>ist für ein funktionierendes AppleTalk-Netzwerk notwendig.</li><li>Als Service Location Protocol und Multicast DNS wird als Teilimplementierung von Zeroconf Multicast (Rendezvous - inzwischen Bonjour) betrieben </li><ul><li>automatische Zuweisung von IP-Adressen ohne DHCP-Server</li></ul><ul><li>übersetzen von Hostnamen in IP-Adressen ohne DNS-Server</li></ul><ul><li>automatisches Finden von Diensten im lokalen Netzwerk ohne einen zentralen Directory-Server</li></ul><li>In Windows wird es im Simple Service Discovery Protocol benutzt</li><li>Weitere Multicast-Protokolle</li><ul><li>Internet Relay Chat (IRC) bildet Netzwerke, welche einen einfachen TCP-basierten Multicast-Baum realisieren - wer hätte das gedacht ^^
</li></ul><ul><li>Es wird überlegt in Jabber Multicast nach zurüsten.

</li></ul></ul></li><li>Und das geht jetzt auch über das Internet oder wie jetzt?
Jein... also:
Multicast-Pakete werden von den meisten Routern im Internet nicht verarbeitet. Deswegen werden multicastfähige Teilnetze über Tunnel zu Multicast Backbones (MBones) verbunden.
Um Multicast-Pakete zwischen mehreren Netzen zu koordinieren, werden spezielle Multicast-Routing-Protokolle verwendet.

</li><li>Ahja... sehr schön - kann da nix passieren / durcheinander kommen?
Es existieren bei der Verwendung bestimmter Adressbereiche einiger Switches Probleme bei der Weiterleitung von Multicastnachrichten.
Die Adressen von 224.0.0.0 bis 224.255.255.255 sind für Routingprotokolle reserviert und für diese Adressen sendet der Router keine IP-Multicast-Datagramme. Die Adressen von 239.0.0.0 bis 239.255.255.255 sind für scoping reserviert, eine Weiterleitung innerhalb dieses Adressbereichs ist ebenfalls Switch abhängig. Adressen im Bereich 225.x.x.x bis 238.x.x.x sind frei verfügbar.

</li><li>Nachwort:
Multicasting wird wieder populär, weil IPTV darauf basiert.
Für verteilte Chat-Netzwerke wurde mittlerweile allgemein eingesehen, dass sie nicht mittels IP-Multicast realisiert werden können. 
Der Einsatz weiterer <span style="font-weight: bold;">Multicast-Protokolle ist daher unumgänglich</span>.&nbsp; Na da haben wirs!

</li></ol>
Schamlos kopiert von <a href="http://de.wikipedia.org/wiki/Multicast">http://de.wikipedia.org/wiki/Multicast</a> - teiweise gekürtzt und ein wenig angepasst.
Die Formulierungen sind auf die frühe Stunde zurück zu führen.


Anschließend zur Entspannung noch ein wenig Java - ein einfacher Chat-Server:
Zuerst der "Server" - Der ja eigentlich auch Teil jedes Clients ist:

&nbsp;&nbsp;&nbsp;<font size="2"> public class NameServer{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // the multicast group address sent to new members
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private static final String GROUP_HOST = "228.5.6.7";&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private static final int PORT = 1234;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // for this server
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private static final int BUFSIZE = 1024;&nbsp;&nbsp; // max size of a message
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private DatagramSocket serverSock;
&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // holds the names of the current members of the multicast group
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private ArrayList groupMembers;&nbsp; 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {&nbsp; // try to create a socket for the server
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; serverSock = new DatagramSocket(PORT);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }catch(SocketException se){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(se);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; groupMembers = new ArrayList();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; waitForPackets();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;  // das ist dann hier wieder die typische Server-While-Schleifen-Methode 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void waitForPackets(){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DatagramPacket receivePacket;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; byte data[];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Ready for client messages");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (true) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data = new byte[BUFSIZE];&nbsp; // set up an empty packet
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; receivePacket = new DatagramPacket(data, data.length);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; serverSock.receive( receivePacket );&nbsp; // wait for a packet
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // extract client address, port, message
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InetAddress clientAddr = receivePacket.getAddress();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int clientPort = receivePacket.getPort();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String clientMsg = new String( receivePacket.getData(), 0, receivePacket.getLength() ).trim();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; processClient(clientMsg, clientAddr, clientPort);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }catch(IOException ioe){&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(ioe);&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } 
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ...
&nbsp;&nbsp;&nbsp; }</font>

Und hier dann noch mal der "Client"-Anteil:

&nbsp;&nbsp;&nbsp; <font size="2">public class MultiChat {
&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // timeout used when waiting in receive()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private static final int TIME_OUT = 5000;&nbsp;&nbsp; // 5 secs
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // max size of a message
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private static final int PACKET_SIZE = 1024; 

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // NameServer address and port constants
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private static final String SERVER_HOST = "localhost";
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private static final int SERVER_PORT = 1234;&nbsp;  

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* The multicast port. The multicast group address is
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; obtained from the NameServer object. */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private static final int GROUP_PORT = 5555;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // for communication with the NameServer
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private DatagramSocket clientSock;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private InetAddress serverAddr;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // for communication with the multicast group
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private MulticastSocket groupSock;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private InetAddress groupAddr;&nbsp;&nbsp;  

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public MultiChat(String nm){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Attempt to register name and get multicast group 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; address from the NameServer */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; makeClientSock();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; waitForPackets();

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } // end of MultiChat();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void makeClientSock(){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {&nbsp;&nbsp; // try to create the client's socket
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; clientSock = new DatagramSocket();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; clientSock.setSoTimeout(TIME_OUT);&nbsp; // include a time-out
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }catch( SocketException se ) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; se.printStackTrace();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;  

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {&nbsp; // NameServer address string --&gt; IP no.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; serverAddr = InetAddress.getByName(SERVER_HOST);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }catch( UnknownHostException uhe) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; uhe.printStackTrace();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; // end of makeClientSock()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void waitForPackets(){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DatagramPacket packet;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; byte data[];

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (true) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data = new byte[PACKET_SIZE];&nbsp;&nbsp;&nbsp; // set up an empty packet
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; packet = new DatagramPacket(data, data.length);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; groupSock.receive(packet);&nbsp; // wait for a packet
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; processPacket(packet);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }catch(IOException ioe){&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(ioe);&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp; // end of waitForPackets()&nbsp; 
&nbsp;&nbsp;&nbsp; }</font>


Wie man ziemlich gut erkennen kann, ist es auch nicht wesentlich anders, als wenn man sich direkt Sockets erstellt. Gefunden habe ich das Ganze in dem Buch "Killer Game Programming in Java" - heißt wirklich so - hin und wieder finden sich da wirklich interessante Dinge besprochen (<a href="https://fivedots.coe.psu.ac.th/%7Ead/jg%20">Link: hier!</a>).

So das wars.
Die Tage wollte ich noch mal bissel was zu OSGi schreiben - so denn das schöne Buch ankommt.
Und aus - leider aktuellem Anlass - zu <a href="http://de.wikipedia.org/wiki/IPMI">IPMI</a> und wieso es eigentlich schon fast unverschämt ist, dass ein _mitgelieferetes_ Linux-Tool fehlerhaft ist und deswegen vom Hersteller empfohlen wird, extra dafür ein Windows aufzusetzen. Nichts gegen Windows, aber wieso liefert man ein fehlerhaftes Tool dann mit?

P.S.: Schreibt mal wieder ;-)
  <div class="flockcredit" style="text-align: right; color: #CCC; font-size: x-small;">Blogged with the <a href="http://www.flock.com/blogged-with-flock" style="color: #999; font-weight: bold;" target="_new" title="Flock Browser">Flock Browser</a></div>]]></description>
         <link>http://www.innoq.com/blog/phaus/2008/07/multicast_genauer_nachgeschaut.html</link>
         <guid>http://www.innoq.com/blog/phaus/2008/07/multicast_genauer_nachgeschaut.html</guid>
        
        
         <pubDate>Tue, 01 Jul 2008 02:24:24 +0100</pubDate>
      </item>
            <item>
         <title>Splines mit dem HTML Canvas Tag</title>
         <description><![CDATA[<font style="font-family: Arial;" size="3">

Splines innerhalb eines Canvas Tags sind mit ein wenig Javascript recht schnell machbar!



(drumherum dann noch den ganzen HTML-Kram denken):</font>


<font size="2"><span style="font-family: Courier;">&lt;canvas width="150" height="150" id="myCanvas1"&gt;&lt;/canvas&gt;</span><br style="font-family: Courier;" /><br style="font-family: Courier;" /><span style="font-family: Courier;">&lt;script type="text/javascript"&gt;</span><br style="font-family: Courier;" /><span style="font-family: Courier;">function draw1(){</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; var myCanvas1 = document.getElementById('myCanvas1');</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; myCanvas1.style.border = "1px black dashed";&nbsp;&nbsp;&nbsp; </span><br style="font-family: Courier;" /><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; var ctx = myCanvas1.getContext('2d');</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; </span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; ctx.beginPath();&nbsp;&nbsp;&nbsp; </span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; ctx.strokeStyle = "#dedede";</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; for (i=1;i&lt;15;i++){</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.moveTo(i*10,0);</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.lineTo(i*10,150); </span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; }</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; for(j=1;j&lt;15;j++){</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.moveTo(0,j*10);</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ctx.lineTo(150,j*10); </span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; }</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; ctx.stroke();&nbsp;&nbsp;&nbsp; </span><br style="font-family: Courier;" /><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; //Steuerpunkte malen (nur zur Verdeutlichung)</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; ctx.beginPath();</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; ctx.lineWidth = 2;</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; ctx.strokeStyle = "rgb(0,200,0)";</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; ctx.moveTo(0,135);</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; ctx.lineTo(60, 130);</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; ctx.arc(60,130,3,0,360, false); </span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; ctx.lineTo(75,75);</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; ctx.lineTo(90,20);</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; ctx.arc(90,20,3,0,360, false);</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; ctx.lineTo(150, 15);</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; ctx.stroke();</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; </span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; //quadraticCurveTo malen </span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; ctx.beginPath();</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; ctx.strokeStyle = "#000000";</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; ctx.moveTo(0,135);</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; ctx.lineWidth = 4;</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; ctx.quadraticCurveTo(60, 130, 75, 75);</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; ctx.moveTo(75,75);</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; ctx.quadraticCurveTo(90, 20, 150, 15);</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&nbsp;&nbsp;&nbsp; ctx.stroke();</span><br style="font-family: Courier;" /><br style="font-family: Courier;" /><span style="font-family: Courier;">} </span><br style="font-family: Courier;" /><span style="font-family: Courier;">draw1();</span><br style="font-family: Courier;" /><span style="font-family: Courier;">&lt;/script&gt;</span></font>


Das macht einem dann ein:

<img src="http://farm3.static.flickr.com/2308/2478911777_832148f5ce.jpg?v=0" style="" title="" alt="" />


<font style="font-family: Arial;" size="3">Das ganze funktioniert mit Firefox ab Version 1.5 (aber erst ab 2.x gehen auch </font><font size="2"><span style="font-family: Courier;"><font style="font-family: Arial;" size="3">quadratic Splines), Opera 9 und neueren Safaries.

Infos hier:
<a href="http://en.wikipedia.org/wiki/Canvas_%28HTML_element%29">Wikipedia Canvas Tag</a>
<a href="http://developer.mozilla.org/en/docs/Canvas_tutorial:Basic_usage">Mozilla Dev Page (sehr zu empfehlen)</a>
</font></span></font><font size="2"><span style="font-family: Courier;"><font style="font-family: Arial;" size="3"><a href="http://www.whatwg.org/specs/web-apps/current-work/#canvas">whatwg.org</a> - watt immer das ist.. steht auch n bissel was zu</font></span></font>
<font size="2"><span style="font-family: Courier;"><font style="font-family: Arial;" size="3">Und zu guter Letzt <a href="http://developer.apple.com/documentation/AppleApplications/Reference/SafariJSRef/Classes/Canvas.html#//apple_ref/doc/uid/-CJBCECGI.html%23//apple_ref/doc/uid/">DIE (besagte) Apple Dev Page</a>

Die Seite von Apple ist angeblich nicht mehr gültig, aber es geht damit einwandfrei...
Die grünen Linien habe ich nur gemacht, damit man die Stützpunkte der Splines besser sehen kann.

Ach was war die CG-Vorlesung doch schön :D
</font>
</span></font>  <div class="flockcredit" style="text-align: right; color: #CCC; font-size: x-small;">Blogged with the <a href="http://www.flock.com/blogged-with-flock" style="color: #999; font-weight: bold;" target="_new" title="Flock Browser">Flock Browser</a></div>]]></description>
         <link>http://www.innoq.com/blog/phaus/2008/05/splines_mit_dem_html_canvas_ta.html</link>
         <guid>http://www.innoq.com/blog/phaus/2008/05/splines_mit_dem_html_canvas_ta.html</guid>
        
        
         <pubDate>Sat, 10 May 2008 03:11:09 +0100</pubDate>
      </item>
            <item>
         <title>NetBeans IDE 6.1 Beta Blogging Contest</title>
         <description><![CDATA[<img src="http://www.netbeans.org/images/competition/61blog-contest-logo-trans.gif" style="margin: 0pt auto 10px; display: block; text-align: center;" title="" alt="" /><font size="5">Preamble:</font>

So i just decided to use the newst version of Netbeans (6.1 beta) to dive deeper into (Ruby on Rails) RoR. Currently i am basically a Developer, concentrated on Java. During my "Diplomarbeit" i was focused on JEE in interplay with YUI. To be honest, i had almost&nbsp; no&nbsp; encounters with RoR - beside from a project where i mainly was responsible for the HTML/Template work. 

Before using Java, i was primary a PHP-Guy. So... yep there is already a big heritage to Script-Languages.


<font size="5">The cast:
<font size="3">
</font></font>the protagonist:&nbsp;&nbsp;&nbsp; Philipp Haußleiter, me, myself and i. I just finished my study an have around a month free time.

featured parts:&nbsp;&nbsp;  &nbsp; 
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  technical advice (i just hope this at least): <a href="http://ghadir.de/blog">Phillip Ghadir</a>, <a href="http://www.innoq.com/blog/st">Stefan Tilkov</a>, <a href="http://www.innoq.com/blog/wvk">Willem van Kerkhof</a>, ... from innoQ
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp; artistic advice (currently on travel): Michael Wolff from <a href="http://3strom.de">3strom.de</a>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  beta testing crowd:&nbsp;&nbsp;  still on casting :-).
locations:&nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  &nbsp;&nbsp;  somewhere in Germany 
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; on a Macbook (2,16 Ghz/3GB) 
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; with Mac OS 10.5.2 with Java 6 DP[1] and Netbeans 6.1 beta


<font size="5">The challenge:
</font>  &nbsp;&nbsp;  &nbsp;&nbsp;  
&nbsp;
If you plan to start developing in Ruby on Rails, there is always this - "Hello World"-Equivalent: writing a Web-Blog. So i think for me - as a beginner - it would be a good start. Of course i will try to bring in some special taste ;-). I am currently using Wordpress 2.5 for my private Blogging-experience. So bar is already&nbsp; on a high level. So trying to beat WP, would be suicide. So in opposite to this, i will focus on just a few functions:

based on RoR with Ruby/JRuby - NB 6.1 seems to provide an easier change between both VMs
better Upload-Handling with search-functions
out-of-the-box anti-spam captchas[2]
 JavaScript-enabled behaviour (yeah... Web 2.0 ^^) - also for testing the new JavaScript-functions in NB 6.1



So currently i figure out some Database-model and trying to get notified by Netbeans.org[3].

[1] http://developer.apple.com/java/download
[2] http://en.wikipedia.org/wiki/Captcha
[3] http://www.netbeans.org/competition/blog-contest-form.html
<font size="5"></font><font size="5">&nbsp;



</font>

  <div class="flockcredit" style="text-align: right; color: #CCC; font-size: x-small;">Blogged with the <a href="http://www.flock.com/blogged-with-flock" style="color: #999; font-weight: bold;" target="_new" title="Flock Browser">Flock Browser</a></div><!-- technorati tags begin --><p style="font-size:10px;text-align:right;">Tags: <a href="http://technorati.com/tag/netbeans6.1Ruby%20Rails%20Blog" rel="tag">netbeans6.1Ruby Rails Blog</a></p><!-- technorati tags end -->]]></description>
         <link>http://www.innoq.com/blog/phaus/2008/04/netbeans_ide_61_beta_blogging.html</link>
         <guid>http://www.innoq.com/blog/phaus/2008/04/netbeans_ide_61_beta_blogging.html</guid>
        
        
         <pubDate>Wed, 02 Apr 2008 16:28:16 +0100</pubDate>
      </item>
            <item>
         <title>Idee!  Lerne RoR! ... und da ist noch dieser NetBeans 6.1 Contest!</title>
         <description><![CDATA[Ich habe mir fest vorgenommen mich in der freien Zeit ein wenig mehr mit RoR zu befassen. 
Ich dache mir mit dem RoR-Pendant zu "Hello World" anzufangen und mich an das Erstellen einen Web-Blogs zu wagen. Natürlich hoffe ich mit den 08/15 Funktionen schnell durch zu sein - verspricht das RoR nicht auch? Ich habe ein paar grundsätzliche Dinge, die mir - selbst an der aktuellsten[1] - Wordpress Version aufstoßen:
&nbsp; * Dem Kommentar-Spam lässt sich nur durch Plug-Ins Herr werden
&nbsp; * Upload/Posten von Dateien ist immer noch ein Graus, auch wenn es mittlerweile WYSIWYG-Editoren gibt.

Movable-Type ist meiner Meinung auch eher funktional, als angenehm ;-).

Hierbei nutze ich nun testweise die neue Version von Netbeans, welche als 6.1 beta erhältlich ist.

   
Auf der Netbeans-Seite gibt es zudem eine Art Gewinnspiel, in dem man sein Blog angeben kann und dieses dann in eine Auswahl zu den besten Netbeans 6.1 Einführungen kommt [2]. Ist die Teilnahme an solchen "Maßnahmen" mit innoQ-Blogs eigentlich gestattet? Ansonsten müsste ich da auf mein eigenes Blog dann zurückgreifen.

Letztendlich ist mir heute auch schon ein Fehler aufgefallen:
Nutze ich die Java 6 Preview Version von Apple, bleiben einige Wizards hängen.
Dies ist bei Java- sowie Ruby-Anwendungen der Fall. Eine Lösung fand sich zum Glück auch schon[3].


[1] http://de.wordpress.org/wordpress-2.5-de_DE.zip
[2] http://www.netbeans.org/competition/blog-contest.html?cid=923686
[3] http://teera.seriyagroup.com/blog/index.php/2008/03/04/netbeans-6-and-mac-java-6-developer-preview-9-project-wizard-hangs-problem/
<div class="flockcredit" style="text-align: right; color: #CCC; font-size: x-small;">Blogged with the <a href="http://www.flock.com/blogged-with-flock" style="color: #999; font-weight: bold;" target="_new" title="Flock Browser">Flock Browser</a></div>]]></description>
         <link>http://www.innoq.com/blog/phaus/2008/04/netbeans_61_beta_contest.html</link>
         <guid>http://www.innoq.com/blog/phaus/2008/04/netbeans_61_beta_contest.html</guid>
        
        
         <pubDate>Tue, 01 Apr 2008 23:44:27 +0100</pubDate>
      </item>
            <item>
         <title>the end?</title>
         <description>Nach dem Countdown nach bin ich nun am -34. Tag.... :D.
Wie dem auch sei. Ich bin durch, fertig - es ist vollbracht.... (hier folgende weitere ausschmückende Beschreibungen).

Da ich eigentlich nun nix mehr zu schreiben hätte, könnte ich hier ein großes CLOSED Schield aufhängen.
Aber ich denke, da ich den April off habe (ein wenig Urlaub machen und Ordnung machen und so...), werde ich vielleicht über ein paar Dinge schreiben, die mir so im Kopf rumschwirren, also Projekte, die ich irgendwann mal (in naher/ferner Zukunft) in Angriff nehmen möchte.

Auch hier sind Kommentare natürlich herzlichst willkommen.</description>
         <link>http://www.innoq.com/blog/phaus/2008/03/the_end.html</link>
         <guid>http://www.innoq.com/blog/phaus/2008/03/the_end.html</guid>
        
        
         <pubDate>Fri, 28 Mar 2008 22:24:44 +0100</pubDate>
      </item>
            <item>
         <title>SSL erzwingen in einem Java Application Server</title>
         <description><![CDATA[Morgen :-),

so langsam bin ich dabei alle meine Problem gelöst zu bekommen :-) - ja wird auch Zeit :-D.
Bezogen auf diesen (http://www.innoq.com/blog/phaus/2007/12/zum_jahresende.html) Post:

Ich bin an der Implementierung mit JAAS noch dran, allerdings habe ich herausgefunden, dass man dem Server einen Filter unterschieben kann, der bei jedem Aufruf überprüft, ob eine SSL Verbindung besteht, und wenn dies nicht der Fall ist, diese per Redirect erzwingt.
Das ganze funktioniert über Filter (wie es ja Ruby on Rails auch macht).

Man erstellt sich eine Klasse, welche javax.servlet.Filter implementiert.
Diese bindet man dann per web.xml ein:

&nbsp;&nbsp;&nbsp; &lt;filter&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-name&gt;SSLFilter&lt;/filter-name&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-class&gt;de.hausswolff.cotodo.security.SSLFilter&lt;/filter-class&gt;
&nbsp;&nbsp;&nbsp; &lt;/filter&gt;
&nbsp;&nbsp;&nbsp; &lt;filter-mapping&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-name&gt;SSLFilter&lt;/filter-name&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&nbsp;&nbsp;&nbsp; &lt;/filter-mapping&gt;&nbsp; 

D.h. alle Anfragen, die an die Applikation gesendet werden, werden durch diesen Filter geschickt.
Der Filter im einzelnen vergleicht ob request.getScheme() == "https" ist. ansonsten redirected er einfach auf entsprechnede Seite.
In meinem Fall (da eine nicht-https Verbindung nur bei einem nicht angemeldeten Benutzer vorhanden ist auf eine Login-Seite)
Ich hoffe, dass ich morgen dann meine Anmeldung vervollständigen kann.

Für alle die sich noch näher mit den Feature von JEE 5 befassen wollen:
Unter http://java.sun.com/developer/releases/petstore/&nbsp; kann man sich mit petstore eine Beispielanwendung herunterladen, die die Neuerungen (inkl. AJAX) demonstriert. <a href="http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/Ebank.html">Duke's Bank</a> scheint demnach nicht mehr genutzt zu werden :-)

   <p style="text-align: right; font-size: 8px">Blogged with <a href="http://www.flock.com/blogged-with-flock" title="Flock" target="_new">Flock</a></p>]]></description>
         <link>http://www.innoq.com/blog/phaus/2008/02/ssl_erzwingen_in_einem_java_ap.html</link>
         <guid>http://www.innoq.com/blog/phaus/2008/02/ssl_erzwingen_in_einem_java_ap.html</guid>
        
        
         <pubDate>Thu, 07 Feb 2008 03:33:05 +0100</pubDate>
      </item>
            <item>
         <title>mal wieder.... REST</title>
         <description><![CDATA[Guten Morgen!
Weil ich grade darüber am schreiben bin, mal wieder was zum Thema:

<font size="4">How I Explained REST to My Wife</font>
<quote>
</quote><div style="margin-left: 40px;">Wife: Who is Roy Fielding?

Ryan: Some guy. He's smart.

Wife: Oh? What did he do?

Ryan: He helped write the first web servers and then did a ton of research explaining why the web works the way it does. His name is on the specification for the protocol that is used to get pages from servers to your browser.

Wife: How does it work?

Ryan: The web?

Wife: Yeah.

Ryan: Hmm. Well, it's all pretty amazing really. And the funny thing is that it's all very undervalued. The protocol I was talking about, HTTP, it's capable of all sorts of neat stuff that people ignore for some reason.

Wife: You mean http like the beginning of what I type into the browser?

Ryan: Yeah. That first part tells the browser what protocol to use. That stuff you type in there is one of the most important breakthroughs in the history of computing.

Wife: Why?

Ryan: Because it is capable of describing the location of something anywhere in the world from anywhere in the world. It's the foundation of the web. You can think of it like GPS coordinates for knowledge and information.

Wife: For web pages?

Ryan: For anything really. That guy, Roy Fielding, he talks a lot about what those things point to in that research I was talking about. The web is built on an architectural style called REST. REST provides a definition of a resource, which is what those things point to.

Wife: A web page is a resource?

Ryan: Kind of. A web page is a representation of a resource. Resources are just concepts. URLs--those things that you type into the browser...

Wife: I know what a URL is..

Ryan: Oh, right. Those tell the browser that there's a concept somewhere. A browser can then go ask for a specific representation of the concept. Specifically, the browser asks for the web page representation of the concept.

Wife: What other kinds of representations are there?

Ryan: Actually, representations is one of these things that doesn't get used a lot. In most cases, a resource has only a single representation. But we're hoping that representations will be used more in the future because there's a bunch of new formats popping up all over the place.

Wife: Like what?

Ryan: Hmm. Well, there's this concept that people are calling Web Services. It means a lot of different things to a lot of different people but the basic concept is that machines could use the web just like people do.

Wife: Is this another robot thing?

Ryan: No, not really. I don't mean that machines will be sitting down at the desk and browsing the web. But computers can use those same protocols to send messages back and forth to each other. We've been doing that for a long time but none of the techniques we use today work well when you need to be able to talk to all of the machines in the entire world.

Wife: Why not?

Ryan: Because they weren't designed to be used like that. When Fielding and his buddies started building the web, being able to talk to any machine anywhere in the world was a primary concern. Most of the techniques we use at work to get computers to talk to each other didn't have those requirements. You just needed to talk to a small group of machines.

Wife: And now you need to talk to all the machines?

Ryan: Yes - and more. We need to be able to talk to all machines about all the stuff that's on all the other machines. So we need some way of having one machine tell another machine about a resource that might be on yet another machine.

Wife: What?

Ryan: Let's say you're talking to your sister and she wants to borrow the sweeper or something. But you don't have it - your Mom has it. So you tell your sister to get it from your Mom instead. This happens all the time in real life and it happens all the time when machines start talking too.

Wife: So how do the machines tell each other where things are?

Ryan: The URL, of course. If everything that machines need to talk about has a corresponding URL, you've created the machine equivalent of a noun. That you and I and the rest of the world have agreed on talking about nouns in a certain way is pretty important, eh?

Wife: Yeah.

Ryan: Machines don't have a universal noun - that's why they suck. Every programming language, database, or other kind of system has a different way of talking about nouns. That's why the URL is so important. It let's all of these systems tell each other about each other's nouns.

Wife: But when I'm looking at a web page, I don't think of it like that.

Ryan: Nobody does. Except Fielding and handful of other people. That's why machines still suck.

Wife: What about verbs and pronouns and adjectives?

Ryan: Funny you asked because that's another big aspect of REST. Well, verbs are anyway.

Wife: I was just joking.

Ryan: It was a funny joke but it's actually not a joke at all. Verbs are important. There's a powerful concept in programming and CS theory called polymorphism. That's a geeky way of saying that different nouns can have the same verb applied to them.

Wife: I don't get it.

Ryan: Well.. Look at the coffee table. What are the nouns? Cup, tray, newspaper, remote. Now, what are some things you can do to all of these things?

Wife: I don't get it...

Ryan: You can get them, right? You can pick them up. You can knock them over. You can burn them. You can apply those same exact verbs to any of the objects sitting there.

Wife: Okay... so?

Ryan: Well, that's important. What if instead of me being able to say to you, "get the cup," and "get the newspaper," and "get the remote"; what if instead we needed to come up with different verbs for each of the nouns? I couldn't use the word "get" universally, but instead had to think up a new word for each verb/noun combination.

Wife: Wow! That's weird.

Ryan: Yes, it is. Our brains are somehow smart enough to know that the same verbs can be applied to many different nouns. Some verbs are more specific than others and apply only to a small set of nouns. For instance, I can't drive a cup and I can't drink a car. But some verbs are almost universal like GET, PUT, and DELETE.

Wife: You can't DELETE a cup.

Ryan: Well, okay, but you can throw it away. That was another joke, right?

Wife: Yeah.

Ryan: So anyway, HTTP--this protocol Fielding and his friends created--is all about applying verbs to nouns. For instance, when you go to a web page, the browser does an HTTP GET on the URL you type in and back comes a web page.

Web pages usually have images, right? Those are separate resources. The web page just specifies the URLs to the images and the browser goes and does more HTTP GETs on them until all the resources are obtained and the web page is displayed. But the important thing here is that very different kinds of nouns can be treated the same. Whether the noun is an image, text, video, an mp3, a slideshow, whatever. I can GET all of those things the same way given a URL.

Wife: Sounds like GET is a pretty important verb.

Ryan: It is. Especially when you're using a web browser because browsers pretty much just GET stuff. They don't do a lot of other types of interaction with resources. This is a problem because it has led many people to assume that HTTP is just for GETing. But HTTP is actually a general purpose protocol for applying verbs to nouns.

Wife: Cool. But I still don't see how this changes anything. What kinds of nouns and verbs do you want?

Ryan: Well the nouns are there but not in the right format.

Think about when you're browsing around amazon.com looking for things to buy me for Christmas. Imagine each of the products as being nouns. Now, if they were available in a representation that a machine could understand, you could do a lot of neat things.

Wife: Why can't a machine understand a normal web page?

Ryan: Because web pages are designed to be understood by people. A machine doesn't care about layout and styling. Machines basically just need the data. Ideally, every URL would have a human readable and a machine readable representation. When a machine GETs the resource, it will ask for the machine readable one. When a browser GETs a resource for a human, it will ask for the human readable one.

Wife: So people would have to make machine formats for all their pages?

Ryan: If it were valuable.

Look, we've been talking about this with a lot of abstraction. How about we take a real example. You're a teacher - at school I bet you have a big computer system, or three or four computer systems more likely, that let you manage students: what classes they're in, what grades they're getting, emergency contacts, information about the books you teach out of, etc. If the systems are web-based, then there's probably a URL for each of the nouns involved here: student, teacher, class, book, room, etc. Right now, getting the URL through the browser gives you a web page. If there were a machine readable representation for each URL, then it would be trivial to latch new tools onto the system because all of that information would be consumable in a standard way. It would also make it quite a bit easier for each of the systems to talk to each other. Or, you could build a state or country-wide system that was able to talk to each of the individual school systems to collect testing scores. The possibilities are endless.

Each of the systems would get information from each other using a simple HTTP GET. If one system needs to add something to another system, it would use an HTTP POST. If a system wants to update something in another system, it uses an HTTP PUT. The only thing left to figure out is what the data should look like.

Wife: So this is what you and all the computer people are working on now? Deciding what the data should look like?

Ryan: Sadly, no. Instead, the large majority are busy writing layers of complex specifications for doing this stuff in a different way that isn't nearly as useful or eloquent. Nouns aren't universal and verbs aren't polymorphic. We're throwing out decades of real field usage and proven technique and starting over with something that looks a lot like other systems that have failed in the past. We're using HTTP but only because it helps us talk to our network and security people less. We're trading simplicity for flashy tools and wizards.

Wife: Why?

Ryan: I have no idea.

Wife: Why don't you say something?

Ryan: Maybe I will.
</div>

<hr>
Quelle: <a href="http://tomayko.com/articles/2004/12/12/rest-to-my-wife">Ryan Tomayko's Blog: How I Explained REST to My Wife</a>

und hier mal ein Ausblick wie das ganze bei mir aussieht: 

<a title="COTODO getUserAsResource KollabDia" href="http://www.flickr.com/photos/8964677@N02/2237645331/"><img style="width: 360px; height: 297px;" src="http://static.flickr.com/2163/2237645331_bccdbcbab3_m.jpg" border="0" /></a><p style="text-align: right; font-size: 8px">Blogged with <a href="http://www.flock.com/blogged-with-flock" title="Flock" target="_new">Flock</a></p>]]></description>
         <link>http://www.innoq.com/blog/phaus/2008/02/mal_wieder_rest.html</link>
         <guid>http://www.innoq.com/blog/phaus/2008/02/mal_wieder_rest.html</guid>
        
        
         <pubDate>Sun, 03 Feb 2008 04:12:01 +0100</pubDate>
      </item>
            <item>
         <title>OFFTOPIC: texten mit LaTeX</title>
         <description><![CDATA[Es gibt 1001 Gründe, wieso ich jetzt etwas zu LaTeX unter MacOS schreibe.
Einer mag sein, dass ich grade - zufälligerweise - LaTeX intensiv nutze.
Ein weiterer, dass ich grade über einen ziemlich dummen Bug unter MacOS Leopard 10.5.1 gestoßen bin, der es einem (und vor allem grade MIR) unmöglich macht, mein schönes LaTeX-Dokument (nein ich sage NICHT was es ist) auszudrucken.
Siehe auch dazu: <a href="http://groups.google.com/group/de.comp.text.tex/browse_thread/thread/13d5a247eae2c991/0bcd9454bc33fd95">hier</a>

Ach noch n Bug: Konnte man unter MacOS 10.4.x noch recht simpel mit
&nbsp;ifconfig ethX lladdr
oder 
&nbsp;ifconfig ethX ether
noch relativ angenehm einfach die MAC Adresse seines Netdevices ändern, geht das seltsamerweise unter 10.5 nicht mehr. In den man-pages steht es aber noch. Ich benutze nun seit 10.3 n Mac und plötzlich kommen die Bugs :-/.

Noch mal zum Thema LaTeX:
Wer sich schon immer gefragt hat, wie man denn unter <a href="http://www.xm1math.net/texmaker">TexMaker</a> oder <a href="http://www.uoregon.edu/%7Ekoch/texshop">TexShop</a> eingetippte Umlaute in sein Latex-Dokument bekommt, der sollte es mal mit diesen Einstellungen versuchen:

&nbsp;\usepackage[T1]{fontenc}
&nbsp;\usepackage[applemac]{inputenc}
&nbsp;\usepackage[ngerman]{babel}

Die tex-Datei sollte man dann bitte als MacOS-Latin1 abspeichern und nicht als UTF8. Gleiches gilt übrigens für alle Listing (Quellcode) Dateien.
Hat gedauert, bis ich darauf kam. Hatte die natürlich alle als UTF8 und in guter Manier alle Kommentare in Deutsch und mit Umlauten.


OFFOFFTOPIC:
Ich habe noch bissel Platz im Auto für Donnerstag. Wer noch ne Fahrgelegenheit braucht, kann sich ja einfach bei mir melden.

Ich teste jetzt noch ob der Acrobat Reader mein PDF will (und sowas unter MacOS) *grml*
   <p style="text-align: right; font-size: 8px">Blogged with <a href="http://www.flock.com/blogged-with-flock" title="Flock" target="_new">Flock</a></p>

P.S.: ich vermisse irgendwie ein Wiki :-o]]></description>
         <link>http://www.innoq.com/blog/phaus/2008/01/offtopic_texten_mit_latex.html</link>
         <guid>http://www.innoq.com/blog/phaus/2008/01/offtopic_texten_mit_latex.html</guid>
        
        
         <pubDate>Wed, 30 Jan 2008 03:16:38 +0100</pubDate>
      </item>
            <item>
         <title>Upgrade - Downgrade - Löschen - Upgrade: Läuft</title>
         <description><![CDATA[Mal wieder ne Stellungnahme:

Da ich u.a. eine Query machen möchte, ob zum Beispiel ein Benutzer mit einer bestimmten Email schon existiert, hatte ich bisher folgende URI zum Abfragen:

&nbsp;http://localhost:8080/cotodo/resources/users/like/?cat=email&amp;val=Test@test.com/

Das lief auch wunderbar. Wen es interessiert, der Code dazu schaut so aus:

&nbsp;&nbsp;&nbsp; @HttpMethod("GET")
&nbsp;&nbsp;&nbsp; @UriTemplate("like/")
&nbsp;&nbsp;&nbsp; @ProduceMime({"application/xml", "application/json"})
&nbsp;&nbsp;&nbsp; public UsersConverter getLikeQuery(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @QueryParam("val") @DefaultValue("") String val,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @QueryParam("cat") @DefaultValue("email") String cat ) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new UsersConverter(getEntitiesLike(cat, val), context.getAbsolute());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } finally {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PersistenceService.getInstance().close();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp; }

Allerdings wäre eine schönere URI ala 
&nbsp;http://localhost:8080/cotodo/resources/users/email/like/philipp@haussleiter.de/
denkbar.

Ich habe mich dann heute mal hingesetzt, um auf eine neuere JSR311 Version (Version 0.5) zu updaten. Eigentlich sollte so allmählich die Final kommen, aber nungut, man weiß ja nicht was für Fehler noch kommen mögen.
Kurzum: Es hat sich einiger geändert. Ist wohl das Problem, wenn man mit nicht spezifizierten Packeten arbeitet :-).
Hier mal ein paar Änderungen:

@HttpMethod ist verkürzt worden:

aus @HttpMethod("GET") wird @GET, aus @HttpMethod("POST") wird @POST usw.

getAbsolute() heißt nun getAbsolutePath(), ansonsten sind mir keine Änderungen aufgefallen.

Der URI Builder (eine statische Klasse, um URIs zusammen zu bauen) wurde umbenannt - was meiner Meinung nach einleuchtender ist nun:
Aus:
&nbsp;Builder.created(context.getAbsolute().resolve(entity.getUserId() + "/")).build();
wird nun:
&nbsp;Response.created(context.getAbsolutePath().resolve(entity.getUserId() + "/")).build();

Da in beiden Fällen der Rückgabewert vom Typ Response ist, ist letzteres einleuchtender.

Mit der neuen Version 0.5 ändert sich obige Methode folgendermaßen:

&nbsp;&nbsp;&nbsp; @GET
&nbsp;&nbsp;&nbsp; @Path("{cat}/like/{val}/")
&nbsp;&nbsp;&nbsp; //@UriTemplate("like/")
&nbsp;&nbsp;&nbsp; @ProduceMime({"application/xml", "application/json"})
&nbsp;&nbsp;&nbsp; public UsersConverter getLikeQuery(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @UriParam("val") @DefaultValue("") String val,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @UriParam("cat") @DefaultValue("email") String cat ) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new UsersConverter(getEntitiesLike(cat, val), context.getAbsolutePath());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } finally {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PersistenceService.getInstance().close();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp; }

Und tut nun auch direkt was sie soll. Ein unschönes (weil sicherheitskritisches) Problem habe ich allerdings in der getEntitiesLike Methode:
Ich muss in den JPQL-Query-String die variabel cat direkt einfügen, über parameter scheint es nicht zu gehen (ist wohl wirklich nur für variable werte vorgesehen). Ich muss noch mal suchen, ob es eine Art SQL_escape methode gibt. Ich will ja nun keine SQL-Injektion hinauf beschwören.

Abschließen hat mich das Update einen guten Teil des Morgens gekostet.
Letztendlich war wohl eine Jar version von ASM (wird u.a. von maven2 benutzt, aber von glassfish benötigt) fehlerhaft.
Es kam andauernd: 
&nbsp;java.lang.NoClassDefFoundError: org/objectweb/asm/ClassVisitor
Obwohl die Klasse definitiv im vorhandenen jar zu finden ist!

Letztendlich habe ich dann alle meine jars mal gelöscht und Schritt für Schritt neu hinzugefügt.
Es hat wohl tatsächlich etwas mit fehlerhaften Referencen zu tun. Das gleiche Problem triff wohl auch bei der Benutztung von Hibernate auf.

Heute Abend, oder morgen schreibe ich dann noch etwas dazu, wie ich ein skizziertes HTML Formular per JS DOM Anweisungen erstelle.
Braucht ein wenig Übung, ist aber sauberer und schneller als sich Strings zusammen zu bauen und außerdem bleibt einem in Hinsicht auf AJAX und callback functions eh nichts anderes übrig.
   <p style="text-align: right; font-size: 8px">Blogged with <a href="http://www.flock.com/blogged-with-flock" title="Flock" target="_new">Flock</a></p>]]></description>
         <link>http://www.innoq.com/blog/phaus/2008/01/upgrade_downgrade_loschen_upgr.html</link>
         <guid>http://www.innoq.com/blog/phaus/2008/01/upgrade_downgrade_loschen_upgr.html</guid>
        
        
         <pubDate>Mon, 28 Jan 2008 16:05:13 +0100</pubDate>
      </item>
            <item>
         <title>1. GUI und die Sicherheit</title>
         <description><![CDATA[Die letzte Zeit habe ich mehr mit Schreiben verbracht. Nachdem ein JavaScript-Unterbau soweit lauffähig ist, habe ich angefangen, meine GUI-Skizzen soweit wie möglich einzubauen:

<a title="COTODO Alpha Screen" href="http://www.flickr.com/photos/8964677@N02/2204230902/"><img src="http://static.flickr.com/2352/2204230902_4bc7335dc0_m.jpg" border="0" /></a>

Ich bin dazu übergangen, anstatt statischen HTML-Code als String zusammen zu bauen (was eh langsam ist), alle Inhalte aus DOM Objekte zusammen zu setzen. Das hat den großen Vorteil, dass ich Elemente auch im Nachhinein per JavaScript mit Hilfe von Callback-Funktionen verändern kann.
Bisher muss man den Benutzer noch "per Hand" abrufen. Ich hoffe, dass ich bald mit einem laufenden Login aufwarten kann, sodass dem Client quasi ein User gesetzt wird.

Hierbei bin ich jetzt davon weg, eine der eingebauten Funktionen von Tomcat/Glassfish zu nutzen. Letztendlich habe ich meine Benutzerdaten in meiner Datenbank und kann diese ja auch ohne weiteres überprüfen. Ich möchte also die Sicherheitsfragen von der Serverebene auf die Applikationsebene verschieben.

Ich habe nun zwei Probleme zu lösen:
1. Alle Abfragen, die nicht über HTTPS laufen, sollen umgeleitet werden (klassischer Redirekt) - wenn möglich könnte ich das noch nach Mime Type filtern (weil z.B. Bilder und CSS/JS ruhig über normales HTTP laufen können).
Es gibt dafür die Methode response.isSecure(). Ich habe jetzt aber mehrmals gelesen, dass man das tunlichst nicht mit einem Scriptlet in JSP machen soll, sondern das ganze über ein Servlet abhandeln sollte. Es wäre ja auch notwendig, die alte Anfrage so umzubauen, dass der Inhalt (welche Datei angefragt wird), gleich bleibt, aber der Empänger auf SSL gelenkt wird. (und ggf. auf einen anderen Port).
2. Es soll vor jeder Anfrage geprüft werden, ob die SSL-Verbindung einem angemeldeten Benutzer gehört. So dies nicht der Fall ist, soll auf eine Loginseite weitergeleitet werden.

Beide Probleme haben gemeinsam, dass die Überprüfung(en) abgehandelt werden müssen, bevor überhaupt etwas anderes passiert.
Ich hatte jetzt überlegt, dass ich ein Servlet einfach auf /* mappe - also ALLE Anfragen an die Applikation über dieses Servlet laufen.
Ich muss jetzt nur rausfinden, wie ich die "guten" Anfragen (die, von eine authorisierten User) an geeignete Stelle weiterleite.
Dazu müsste ich ja u.a. direkt mein Servlet aufrufen, welches für Jersey/REST meine Anfragen abhandelt. Ein HTTP-konformes Redirect würde ja irgendwie eine Endlosschleife verursachen. Ich lese grade EJB3 in Action und bin auch schon auf ein paar interessante Stellen gestoßen. Was fehlt ist einfach noch der Aha-Effekt.

Nachbemerkung zu JavaScript:
Durch die ganzen - notwendigen - Callbacks und die Nutzung von DOM-Komponenten, kommt es mir langsam vor, als würde ich Java programmieren. Letztendlich sehr zweischneidig:&nbsp; 
A) Man hat Schemata, die funktionieren (weil aus Java bekannt)
B)&nbsp; JavaScript verliert so ein bißchen den Charme einer leichten und Schnellen Scriptsprache. 
   <p style="text-align: right; font-size: 8px">Blogged with <a href="http://www.flock.com/blogged-with-flock" title="Flock" target="_new">Flock</a></p>]]></description>
         <link>http://www.innoq.com/blog/phaus/2008/01/1_gui_und_die_sicherheit.html</link>
         <guid>http://www.innoq.com/blog/phaus/2008/01/1_gui_und_die_sicherheit.html</guid>
        
        
         <pubDate>Sat, 19 Jan 2008 17:32:18 +0100</pubDate>
      </item>
            <item>
         <title>JavaScript DOM Object Parser</title>
         <description><![CDATA[Ich sitze grade mitten drin, meine XML Ausgaben zu zerlegen um an die Daten zu kommen.
Da das teilweise wirklich unübersichtlich wird, habe ich mir zweit Stunden Zeit genommen und mir einen Parser&nbsp; geschrieben, der mir ein beliebiges DOM Objekt als Baum ausgibt.

Aus dieser XML Struktur:

<a title="user.xml.png" href="http://www.flickr.com/photos/8964677@N02/2192847848/"><img src="http://static.flickr.com/2082/2192847848_99f37c67d8_m.jpg" border="0" /></a>

baut er mir zum Beispiel das hier:

<a title="big1.png" href="http://www.flickr.com/photos/8964677@N02/2192058607/"><img src="http://static.flickr.com/2359/2192058607_f3a9b6668f_m.jpg" border="0" /></a>

Um das Ganze noch mal näher zu betrachten:

<a title="small1.png" href="http://www.flickr.com/photos/8964677@N02/2192848178/"><img src="http://static.flickr.com/2323/2192848178_d8c49f8729_m.jpg" border="0" /></a>


Der Parser ansicht befindet sich in einer JS Datei namens Debug.js

Diese bindet man über 

&nbsp;&lt;script type="text/javascript" src="debug.js"&gt;&lt;/script&gt;

ein und mit 

&nbsp;DEBUG.moveDIV(600,25);

kann man das Ausgabefenster noch an eine Stelle verschieben, wo es nicht stört.
Das eigentlich parsen passiert dann so:

&nbsp;DEBUG.showParse(object);

Hierbei kann Object z.B. <span style="font-style: italic;">document</span> sein, als auch zum Beispiel <span style="font-style: italic;">o.responseXML.documentElement.

</span>Das Script selber <a href="haussleiter.de/files/debug.js.zip">ist hier zu finden</a>.<span style="font-style: italic;">
</span>   <p style="text-align: right; font-size: 8px">Blogged with <a href="http://www.flock.com/blogged-with-flock" title="Flock" target="_new">Flock</a></p>]]></description>
         <link>http://www.innoq.com/blog/phaus/2008/01/javascript_dom_object_parser.html</link>
         <guid>http://www.innoq.com/blog/phaus/2008/01/javascript_dom_object_parser.html</guid>
        
        
         <pubDate>Mon, 14 Jan 2008 15:22:30 +0100</pubDate>
      </item>
            <item>
         <title>XSLT - Exkurs</title>
         <description><![CDATA[Weil ichs mal in Erwägung gezogen habe, aber Abstand davon genommen habe, da es eine wirklich nützliche XSLT Lib für JavaScript nocht nicht gibt.
Das Problem ist, dass man XML Daten bekommt (so wie das bei mir der Fall ist), aber diese Daten zum Beispiel als HTML Inseln (siehe letzter Post) in seinen DOM Baum "einhängen" möchte.
Man könnte sich ja jetzt fragen, wieso man dann nicht gleich HTML als Ausgabeformat nutzen möchte, aber letztendlich soll es ja alles schön kompatibel zu anderen Client bleiben und ich denke mal, dass das von mir gewünschte Format alles andere als Standard wäre. Es fehlt also eine Anweisung, um XML in das gewünschte HTML Format zu überführen. Genau das bietet einem <a href="http://de.wikipedia.org/wiki/Xslt">XSLT (Extensible Stylesheet Language Transformation)</a>.
Hierbei wird durch ein XSL-Script fest gelegt, welche Daten wo im Ausgabeformat (in meinem Fall also HTML) landen sollen.

Also nehmen wir folgendes XML File:

<span style="font-weight: bold; font-style: italic;">user.xml:

</span><div style="margin-left: 40px;"><font size="2"><span style="font-style: italic;">&lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&lt;user uri="http://localhost:8080/cotodo/resources/users/3/"&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &lt;email&gt;Test3&lt;/email&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &lt;forename&gt;Test&lt;/forename&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &lt;surname&gt;NeuerTester&lt;/surname&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &lt;userId&gt;3&lt;/userId&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &lt;created uri="http://localhost:8080/cotodo/resources/users/3/tasks/"&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;taskRef uri="http://localhost:8080/cotodo/resources/users/3/tasks/1/"&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;taskId&gt;1&lt;/taskId&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/taskRef&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;taskRef uri="http://localhost:8080/cotodo/resources/users/3/tasks/2/"&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;taskId&gt;2&lt;/taskId&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/taskRef&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &lt;/created&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &lt;groups uri="http://localhost:8080/cotodo/resources/users/3/groups/"&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;groupRef uri="http://localhost:8080/cotodo/resources/users/3/groups/1/"&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;groupId&gt;1&lt;/groupId&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/groupRef&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;groupRef uri="http://localhost:8080/cotodo/resources/users/3/groups/2/"&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;groupId&gt;2&lt;/groupId&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/groupRef&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &lt;/groups&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &lt;inbox uri="http://localhost:8080/cotodo/resources/users/3/tasks/"&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;taskRef uri="http://localhost:8080/cotodo/resources/users/3/tasks/2/"&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;taskId&gt;2&lt;/taskId&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/taskRef&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &lt;/inbox&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &lt;outbox uri="http://localhost:8080/cotodo/resources/users/3/tasks/"&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;taskRef uri="http://localhost:8080/cotodo/resources/users/3/tasks/2/"&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;taskId&gt;2&lt;/taskId&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/taskRef&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &lt;/outbox&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&lt;/user&gt;</span><br style="font-style: italic;" /></font>
</div>Wie man gut erkennt, eine - recht tief - verschachtelte Ansammlung von Datenblöcken. Wichtig für REST sind zum Beispiel auch die Referenzen auf die verschiedenen Objekte (URIs), um ggf. Objekte vollständig nach zuladen.

Meine gewünschte HTML Ausgabe soll dann so aussehen:

<span style="font-weight: bold; font-style: italic;">user.html:

</span><div style="margin-left: 40px;"><font size="2"><span style="font-style: italic;">&lt;li class="user" id="3" uri="http://localhost:8080/cotodo/resources/users/3/"&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &lt;ul class="attributes"&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;li id="email"&gt;Test3&lt;/li&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;li id="forename"&gt;Test&lt;/li&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;li id="surname"&gt;NeuerTester&lt;/li&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &lt;/ul&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &lt;ul class="groups" style="display:none" uri="http://localhost:8080/cotodo/resources/users/3/groups/"&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;li class="groupRef"&gt;1&lt;/li&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;li class="groupRef"&gt;2&lt;/li&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &lt;/ul&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &lt;ul class="outbox" style="display:none" uri="http://localhost:8080/cotodo/resources/users/3/outbox/"&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;li class="taskRef"&gt;2&lt;/li&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &lt;/ul&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &lt;ul class="inbox" style="display:none" uri="http://localhost:8080/cotodo/resources/users/3/inbox/"&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;li class="taskRef"&gt;2&lt;/li&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &lt;/ul&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &lt;ul class="created" style="display:none" uri="http://localhost:8080/cotodo/resources/users/3/created/"&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;li class="taskRef"&gt;1&lt;/li&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;li class="taskRef"&gt;2&lt;/li&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &lt;/ul&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&lt;/li&gt;</span></font>

</div>Es handelt sich letztendlich um ein Listenelement (welches dann in einer users Liste landet), welches weitere Unterlisten enthält. Die Anzahl der Referenzen habe ich - zur optimaleren Platzausnutzung und zur Übersichtlichkeit - verringert. Letztendlich reicht mir eine Referenz der Liste und kann dann mit Hilfe der RefIds auf die URIs der einzelnen Elemente zugreifen. Das <span style="font-style: italic;">display:none</span> habe ich nur aus dem Grund eingefügt, dass gewisse Elemente nicht sichtbar sein müssen. Mir reicht, dass sie im DOM hinterlegt sind.

Um also so eine Ausgabe zu erreichen benutze ich folgendes Script:


  

<span style="font-weight: bold; font-style: italic;">user.xsl:
</span><span style="font-style: italic;">
</span><div style="margin-left: 40px;"><font size="2"><span style="font-style: italic;">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &lt;xsl:output method="html"/&gt;</span><br style="font-style: italic;" /><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &lt;xsl:template match="/"&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;xsl:element name="li"&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;xsl:attribute name="class"&gt;user&lt;/xsl:attribute&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;xsl:attribute name="id"&gt;&lt;xsl:value-of select="user/userId" /&gt;&lt;/xsl:attribute&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;xsl:attribute name="uri"&gt;&lt;xsl:value-of select="user/@uri" /&gt;&lt;/xsl:attribute&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;xsl:element name="ul"&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;xsl:attribute name="class"&gt;attributes&lt;/xsl:attribute&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;li id="email"&gt;&lt;xsl:value-of select="user/email"/&gt;&lt;/li&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;li id="forename"&gt;&lt;xsl:value-of select="user/forename"/&gt;&lt;/li&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;li id="surname"&gt;&lt;xsl:value-of select="user/surname"/&gt;&lt;/li&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/xsl:element&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;xsl:element name="ul"&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;xsl:attribute name="class"&gt;groups&lt;/xsl:attribute&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;xsl:attribute name="style"&gt;display:none&lt;/xsl:attribute&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;xsl:attribute name="uri"&gt;&lt;xsl:value-of select="user/@uri" /&gt;groups/&lt;/xsl:attribute&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;xsl:for-each select="user/groups/groupRef"&gt;&nbsp;&nbsp;&nbsp; </span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;li class="groupRef"&gt;&lt;xsl:value-of select="groupId"/&gt;&lt;/li&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/xsl:for-each&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/xsl:element&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;xsl:element name="ul"&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;xsl:attribute name="class"&gt;outbox&lt;/xsl:attribute&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;xsl:attribute name="style"&gt;display:none&lt;/xsl:attribute&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;xsl:attribute name="uri"&gt;&lt;xsl:value-of select="user/@uri" /&gt;outbox/&lt;/xsl:attribute&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;xsl:for-each select="user/outbox/taskRef"&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;li class="taskRef"&gt;&lt;xsl:value-of select="taskId"/&gt;&lt;/li&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/xsl:for-each&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/xsl:element&gt;&nbsp;&nbsp;&nbsp; </span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;xsl:element name="ul"&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;xsl:attribute name="class"&gt;inbox&lt;/xsl:attribute&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;xsl:attribute name="style"&gt;display:none&lt;/xsl:attribute&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;xsl:attribute name="uri"&gt;&lt;xsl:value-of select="user/@uri" /&gt;inbox/&lt;/xsl:attribute&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;xsl:for-each select="user/inbox/taskRef"&gt;&nbsp;&nbsp;&nbsp; </span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;li class="taskRef"&gt;&lt;xsl:value-of select="taskId"/&gt;&lt;/li&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/xsl:for-each&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/xsl:element&gt;&nbsp;&nbsp;&nbsp; </span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;xsl:element name="ul"&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;xsl:attribute name="class"&gt;created&lt;/xsl:attribute&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;xsl:attribute name="style"&gt;display:none&lt;/xsl:attribute&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;xsl:attribute name="uri"&gt;&lt;xsl:value-of select="user/@uri" /&gt;created/&lt;/xsl:attribute&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;xsl:for-each select="user/created/taskRef"&gt;&nbsp;&nbsp;&nbsp; </span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;li class="taskRef"&gt;&lt;xsl:value-of select="taskId"/&gt;&lt;/li&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/xsl:for-each&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;/xsl:element&gt;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &lt;/xsl:element&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &lt;/xsl:template&gt;</span><br style="font-style: italic;" /><span style="font-style: italic;">&lt;/xsl:stylesheet&gt;</span></font>

</div>Hierbei gelten folgende Regeln:
Der Zugriff auf die einzelnen Elemente erfolgt über <a href="http://de.wikipedia.org/wiki/XPath">XPath</a>. Also <span style="font-style: italic;">&lt;xsl:value-of select="user/userId" /&gt;</span> bedeute, dass der Wert aus der Hirachie <span style="font-style: italic;">user/</span> geholte wird, welche zwischen den Tags <span style="font-style: italic;">userId</span> steht. Möchte man auf ein Attribute zugreifen, so benutzt man das @ Zeichen. 
Wie z.B. bei <span style="font-style: italic;">&lt;xsl:value-of select="user/@uri" /&gt;</span>. Ich habe mich immer für die "Root" URI entschieden, weil die anderen URIs sich per Definitionem davon ableiten lassen.

wollte man das XML Document nun direkt als HTML ausgeben haben, so fügt man in obiges Dokument unter

&lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;

folgendes ein:

&lt;?xml-stylesheet type="text/xsl" href="user.xsl"?&gt;


Hierbei sollte die Datei natürlich unter dem gleichen Pfad erreichbar sein wir die user.xml. (Aus Testzwecken war das bei mir der Fall). Aber natürlich kann man auch jede andere URL angeben. Das Einbinden entspricht ungefähr dem von einer CSS Datei.

Empfehlenswert zu dem Thema ist:

<a href="http://dev.abiss.gr/sarissa/">sarissa - eine JS Implementierung von XSLT</a>
<a href="http://www.topxml.com/xsl/tutorials/intro/default.asp">Die XSL Tutorials von TopXML</a>
<a href="http://www.drweb.de/xml/index.shtml">XML/XSL Tutorials von DrWeb</a>
und zu guter Letzt:
<a href="http://www.w3schools.com/xsl">Die XML/XSL Tutorials von den W3Schools</a>





<div style="margin-left: 40px;"><span style="font-style: italic;">

</span><span style="font-style: italic;"></span></div><span style="font-style: italic;">
</span><p style="text-align: right; font-size: 8px">Blogged with <a href="http://www.flock.com/blogged-with-flock" title="Flock" target="_new">Flock</a></p>]]></description>
         <link>http://www.innoq.com/blog/phaus/2008/01/xslt_exkurs.html</link>
         <guid>http://www.innoq.com/blog/phaus/2008/01/xslt_exkurs.html</guid>
        
        
         <pubDate>Wed, 09 Jan 2008 19:04:49 +0100</pubDate>
      </item>
            <item>
         <title>Die Nebenläufigkeit</title>
         <description><![CDATA[Ich sitze nun schon seit einiger Zeit an meinem Client und bin dabei, die Funktionalität soweit zu verwirklichen, dass ein einfaches Arbeiten (CRUD), mit jeweils User, Task und Group möglich ist. Ich habe bemerkt, dass die Oberfläche die wenigsten Probleme macht, was eine Herausforderung ist, sind die vielen nebenläufigen Request-Abfragen.

Ich habe (hatte) mich dazu entschlossen (hier mal anhand eines Users), jeweils per JS ein User Objekt (welches von den Attributen her meinem JPA Objekt entspricht), sowie ein UserService Objekt, welches den Zugriff (Ändern/Laden/Speichern/Cachen) meiner User-objekte.
Liegt ein Objekt nicht im lokalen Cache (ein Array aus User-objekten) vor, so soll es Remote vom Server geholt werden. 
Das klappt auch soweit alles. Leider handelt es sich bei dem Request (AJAX-typisch) um einen asynchronen Request,so dass die Daten im Hintergrund geladen werden, während die Verarbeitung im Vordergrund weiter läuft. Es passiert dann des öfteren, dass auf Daten zugegriffen werden soll, die noch nicht vollständig geladen sind. Dies passiert zum Beispiel auch, wenn innerhalb eines Task-Objektes ein User-Objekt abgefragt wird, welches noch nicht lokal im Cache vorhanden ist. Nach einiger Literatur (u.a. auch auf den Developer Seite bei Yahoo) und ein wenig Austausch mit Willem (vielen Danke noch mal hierfür) bin ich nun zu dem Ergebnis gekommen, dass ich meine Architektur so abändere, sodass diese stärker mit Callbacks arbeiten.
YUI sieht hierbei ein Callback-Objekt vor, welches jeweils eine Methode bei Erfolg und eine Methode bei Misserfolg zur Verfügung stellt.
Ein großes Problem ist hierbei aber auch die Übergabe der Referenzen. 

Da zum Beispiel meine UserService Klasse instanziert wird und das Cache Array dann ein Attribut des Objektes ist.
So ist es dann notwendig, dass einer Callback-Klasse diese Referenz ebenfalls zur Verfügung gestellt wird.
Dies kann man u.a. durch ein "Zwischen referenzieren des this-pointers machen:

<div style="margin-left: 40px;"><span style="font-style: italic;">COTODO.UserService.prototype.getRemoteAndCallback = function(id, callback) {</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; function failureHandler(o){</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var out = "COTODO.UserService.getRemote: id="+id;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Referenz steht normalerweise im UserAttribute</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; var rUrl = "resources/users/"+id+"/";&nbsp; </span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var self = this;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; YAHOO.log("Failure handler called; http status: " + o.status, "warn", "User.js");</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; } </span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; YAHOO.util.Connect.asyncRequest('GET', sUrl, { success:callback, failure:failureHandler });</span><br style="font-style: italic;" /><span style="font-style: italic;">};</span>
</div>
Da <span style="font-style: italic;">self</span> in diesem Fall im Bezug auf eine mögliche Callback-Methode innerhalber der Methode getRemoteAndCallback im globalen Kontext steht, ist es ohne weiteres möglich, auf die Methoden von <span style="font-style: italic;">self</span> zu zugreifen.

Im Moment bin ich dabei so Dinge wie:

&nbsp;<span style="font-style: italic;">&nbsp;&nbsp; &nbsp;&nbsp;  &nbsp;&nbsp;  //US = UserService Instanz</span><br style="font-style: italic;" /><div style="margin-left: 40px;"><span style="font-style: italic;">COTODO.TaskService.prototype.getCreatedBy = function(){</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; return US.get(this.created_by);</span><br style="font-style: italic;" /><span style="font-style: italic;">}</span>

</div>Auf eine Callback-Variante um zubauen. Letztendlich sah meine get Methode bisher wie folgt aus:

<div style="margin-left: 40px;"><span style="font-style: italic;">COTODO.UserService.prototype.get = function(id){</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!this.exists(id)){</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this.getRemote(id);</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; COTODO.debug(this.list[id],"get");</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this.list[id];</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; };</span>

</div>Da aber in getRemote ein nebenläufiger Request abgesetzt wird, muss ich das so umbauen, dass die Methodenaufrufe quasi von der "anderen Richtung" her ausgelöst werden, also nach Abschluss des Requestes erst aktiviert wird. Andernfalls kommt es des öfteren zu einem NULL Objekt. 
Meine erste - zugebenermaßen naive Idee - eine Art globales Wait-Flag im User-Objekt zu hinterlegen, um die nebenläufigen Threads zu synchronisieren, habe ich wieder begraben, weil so Dinge wie:

<div style="margin-left: 40px;"><span style="font-style: italic;">while(!US.get(this.created_by).done){}</span>

</div>Sich nur schwer bis gar nicht kontrollieren lassen. Und entweder den Status ändern (also auf TRUE gesetzt werden), obwohl das Objekt noch nicht geladen ist oder einfach in Endlosschleifen verenden.

Eine weitere interessante Möglichkeit wäre die Nutzung von XML-Inseln. Also die Möglichkeit, dass jedes Objekt (und in diesem Objekt dann jeweils eine Callback-Methode) dafür verantwortlich ist, dass seine eigene Daten in den DOM Tree der Seite gesetzt werden.
D.h. jedes User-Objekt würde sicher selber - bei Bedarf - als "li" - node in ein "ul" Element auf der Seite setzen und so auch tatsächlich in der GUI die Userliste&nbsp; füllen. Alle User Attribute könnte man entweder als li Attribute setzen (den Tag in dieser Hinsicht "verschmutzen") oder aber halt in einen versteckten Layer packen. Sicherlich eine interessante Idee, aber letztendlich halt nicht wirklich 100% MVC, aber durchaus gängige Praxis im AJAX Umfeld.

Mein UserService&nbsp; würde dann auch kein&nbsp; internes Cache Array haben - sondern direkt auf&nbsp; den DOM-Knoten zugreifen.

Um den Zugriff zu vereinfachen habe ich mir schon ein paar Ersatz-Methoden geschrieben, um die Dinge zu verkürzen. Wer Prototype kennt, wird sich zuhause fühlen. 
<br style="font-style: italic;" /><div style="margin-left: 40px;"><span style="font-style: italic;">Object.prototype.$V = function(id, num){</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; var num = num || 0;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; try{</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this.$E(id)[num].firstChild.nodeValue;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; }catch(error){</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return null;</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; }</span><br style="font-style: italic;" /><span style="font-style: italic;">};</span><br style="font-style: italic;" /><br style="font-style: italic;" /><span style="font-style: italic;">Object.prototype.$E = function(id){</span><br style="font-style: italic;" /><span style="font-style: italic;">&nbsp;&nbsp;&nbsp; return this.getElementsByTagName(id);</span><br style="font-style: italic;" /><span style="font-style: italic;">};</span>
</div>
Letztendlich werden hier aber noch alle JS-Objekte verändert, sodass auch ein Array besagte Methoden enthält.
Ich werde mal schauen ob sich das irgendwie noch verfeinern lässt.

   <p style="text-align: right; font-size: 8px">Blogged with <a href="http://www.flock.com/blogged-with-flock" title="Flock" target="_new">Flock</a></p>]]></description>
         <link>http://www.innoq.com/blog/phaus/2008/01/die_nebenlaufigkeit.html</link>
         <guid>http://www.innoq.com/blog/phaus/2008/01/die_nebenlaufigkeit.html</guid>
        
        
         <pubDate>Tue, 08 Jan 2008 12:24:28 +0100</pubDate>
      </item>
            <item>
         <title>Zum Jahresende</title>
         <description><![CDATA[Moin...

bevor das Jahr zu Ende geht, und es so scheint, als würde ich nix tun:

Ich bin momentan dabei nach Patchwork Manie meine Texte zusammen zu schreiben - denke aber, dass ich da mal ein paar Tage konzentriert dran sitzen sollte, um mal eine Grundstruktur zu finden.

Weiterhin bin ich momentan dabei, mir einen JavaScript Client zu bauen. Wie vielleicht einiger wissen, benutze ich da das YUI Framework. Dennoch ist es z.B. notwendig, die Entities, welche auf Serverseite (u.a. die JPA Pojos) existieren, auch auf Clientseite abzubilden. Ich bin also momentan dabei, mir mein User.Task und Group Objekt, nebst Abhängigkeiten aufzubauen. Da ich nicht wegen jeder Abhängigkeit einen neuen HTTPRequest senden möchte, speichere ich mir die Objekte in seperate Arrays zwischen und lade die Daten dann nur nach Bedarf nach. Das&nbsp; klappt auch soweit ganz gut, aber letztendlich fehlt es mir irgendwie an den JS Eigenheiten in Bezug auf OOP Programmierung :-D.

Sobald mein Client mit den Grundfunktionen steht, werde ich mich wieder dem Thema Authorisierung/Authentifiszierung über HTTP-AUTH und SSL befassen.
Ist irgendwie ein Riesenbereich und meine bisherigen Erfahrungen sagen mir, dass man es entweder ganz oder gar nicht machen sollte :-). Alleine das Thema Rollenverteilung kann ja schon Bücher füllen. Ich hadere noch ein wenig damit, eine geeignete Lösung zu finden, um alle Request, die nach "/" gehen an ein Formular weiterzuleiten, welches dann über SSL eine Anmeldung realisiert. Weiterhin denke ich, dass ich zumindest alle Anfragen durch eine eigene EJB schleusen müsste, um jeweils Userdaten auf Serverseite anhand der SSL Session zu finden.

Neben dem eBook EJB in Action fand ich u.a. <a href="http://www.ryandelaplante.com/rdelaplante/entry/ssl_and_http_basic_authentication">hier</a> weitere Informationen zum Thema. Wie ich bisher ja schon geschildert habe, realisiere ich den notwendigen realm für die Userdaten meines Java Application Servers über Views in der Datenbank. Letzendlich bleiben aber auch hier noch Fragen offen:

1. Gibt es eine Möglichkeit, alle notwendigen Einstellungen ohne Admin Konsole zu erstellen (also quasi über eine Build Script, welches dem Server dann einen Sec Realm darbietet)
2. Ist das ganze Server unabhängig (also z.B. auf Tomcat und Glassfish beidermaßen gleich lauffähig)
3. (zählt auch eher zu 2) welche der vielen Config Dateien gilt es jetzt zu erweitern ( neben einer web.xml gibt es diverse sun-*.xml)

Ist also noch viel zu tun - nur schön, dass es sich mal wieder herausgestellt hat, dass der JS Anteil relativ leicht von der Hand geht. Es muckt zwar hier und da noch ein wenig auf, aber das bekommt man dann auch recht schnell in den Griff.

Ich wünsche allen ein erfolgreiches 2008 und verweise dann hiermit noch mal auf <a href="http://www.philipp.haussleiter.de/index.php/2007/12/31/und-weil-es-so-schon-war-noch-einmal-auf-deutsch">meinen Post in meinem privaten Blog</a>. (ich kann mir nicht helfen, aber letztendlich muss ich am Schriftbild da noch mal arbeiten :-D)
   <p style="text-align: right; font-size: 8px">Blogged with <a href="http://www.flock.com/blogged-with-flock" title="Flock" target="_new">Flock</a></p>]]></description>
         <link>http://www.innoq.com/blog/phaus/2007/12/zum_jahresende.html</link>
         <guid>http://www.innoq.com/blog/phaus/2007/12/zum_jahresende.html</guid>
        
        
         <pubDate>Mon, 31 Dec 2007 12:41:28 +0100</pubDate>
      </item>
      
   </channel>
</rss>
