<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tobis Blog &#187; Webentwicklung</title>
	<atom:link href="http://blog.aditu.de/category/webentwicklung/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.aditu.de</link>
	<description>Alles rund um Webentwicklung, Fotografie, PHP und weitere interessante Themen</description>
	<lastBuildDate>Wed, 25 Jan 2012 17:30:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Filtern und Bereinigen von HTML mit jsoup</title>
		<link>http://blog.aditu.de/2012/01/25/filtern-und-bereinigen-von-html-mit-jsoup/</link>
		<comments>http://blog.aditu.de/2012/01/25/filtern-und-bereinigen-von-html-mit-jsoup/#comments</comments>
		<pubDate>Wed, 25 Jan 2012 17:30:38 +0000</pubDate>
		<dc:creator>Tobi</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Webentwicklung]]></category>
		<category><![CDATA[Cross Site Scripting]]></category>
		<category><![CDATA[HTML Purifier]]></category>
		<category><![CDATA[htmLawed]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Sicherheit]]></category>
		<category><![CDATA[Validierung]]></category>
		<category><![CDATA[XSS]]></category>

		<guid isPermaLink="false">http://blog.aditu.de/?p=1013</guid>
		<description><![CDATA[Immer wieder stößt man auf den Anwendungsfall, dass Benutzereingaben, die HTML enthalten dürfen, bereinigt werden müssen. Besonders hinsichtlich dem Schutz vor XSS Angriffen führt kein Weg an einem solchen Schritt vorbei. In PHP gibt es hierfür mehrere Bibliotheken wie HTML Purifier Bibliothek oder htmLawed. Besteht die Anforderung, dass bestimmte HTML Eingaben erlaubt sein sollen, so [...]]]></description>
			<content:encoded><![CDATA[<p>Immer wieder stößt man auf den Anwendungsfall, dass Benutzereingaben, die HTML enthalten dürfen, bereinigt werden müssen. Besonders hinsichtlich dem Schutz vor XSS Angriffen führt kein Weg an einem solchen Schritt vorbei. In PHP gibt es hierfür mehrere Bibliotheken wie <a href="http://htmlpurifier.org/">HTML Purifier Bibliothek</a> oder <a href="http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed/">htmLawed</a>.</p>
<p>Besteht die Anforderung, dass bestimmte HTML Eingaben erlaubt sein sollen, so ist der Einsatz einer Bibliothek an dieser Stelle unbedingt notwendig. Es gibt <a href="http://ha.ckers.org/xss.html">zahlreiche Angriffsmöglichkeiten</a>, mit der ein Filter zurecht kommen muss und so kann man nur davon abraten selbst etwas zu bauen (z.b. Textersetzung mittels Regulären Ausdrücken).</p>
<p>Für Java habe ich eine sehr einfache und gute Bibliothek gefunden, die ich an dieser Stelle nur weiterempfehlen kann. <a href="http://jsoup.org">jsoup</a> heißt die schlanke Library, die unter der MIT Lizenz zur Verfügung steht und auch für die Manipulation von HTML Dokumenten zahlreiche Funktionen mit bringt. Zudem wird HTML5 und auch invalides HTML unterstützt.</p>
<p>Die Funktionsweise ist schnell erklärt. Will man jegliches HTML entfernen, so geschieht das mit folgenden Aufruf</p>
<pre class="brush: java; title: ; notranslate">
String userText = &quot;Beispieltext &lt;script&gt;alert('xyz');
        &lt;/script&gt; Beispieltext&quot;;
String cleanText = Jsoup.clean(userText, Whitelist.none());
// cleanText == &quot;Beispieltext  Beispieltext&quot;
</pre>
<p>Wie man sieht, dient ein Whitelist Objekt zur Definition, was erlaubt ist und was nicht. So kann man genau festlegen, welche Tags und welche Attribute zugelassen werden und welche nicht. Folgendes Beispiel erlaubt nur &lt;i&gt; und &lt;b&gt; Tags:</p>
<pre class="brush: java; title: ; notranslate">
String userText = &quot;&lt;a href='beispiel.de'&gt;xyz&lt;/a&gt;
          Bla &lt;i&gt;Blub&lt;/i&gt; Bl&lt;b&gt;ub&lt;/b&gt;&quot;;
String[] allowedTags = {&quot;i&quot;,&quot;b&quot;};
Whitelist whitelist = new Whitelist();
whitelist.addTags(allowedTags);
String cleanText = Jsoup.clean(userText, whitelist);
// cleanText == &quot;xyz Bla &lt;i&gt;Blub&lt;/i&gt; Bl&lt;b&gt;ub&lt;/b&gt;&quot;
</pre>
<p>Die Dokumentation und das JAR File sind auf der Webseite von jsoup zu finden:<br />
<a href="http://jsoup.org">jsoup Website</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aditu.de/2012/01/25/filtern-und-bereinigen-von-html-mit-jsoup/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hintergründe zu selfoss</title>
		<link>http://blog.aditu.de/2011/12/09/hintergrunde-zu-selfoss/</link>
		<comments>http://blog.aditu.de/2011/12/09/hintergrunde-zu-selfoss/#comments</comments>
		<pubDate>Fri, 09 Dec 2011 19:44:38 +0000</pubDate>
		<dc:creator>Tobi</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Projekte]]></category>
		<category><![CDATA[selfoss]]></category>
		<category><![CDATA[Webentwicklung]]></category>

		<guid isPermaLink="false">http://blog.aditu.de/?p=934</guid>
		<description><![CDATA[In einem Gastbeitrag bei phphatesme schreibe ich über selfoss. Dort stelle ich auch die verschiedenen Bibliotheken vor, die ich für den RSS Reader verwende. Also für Interessierte: schaut einfach rein. Herzlichen Dank an Nils, dass er mir die Möglichkeit gegeben hat, selfoss in seinem Blog vorzustellen.]]></description>
			<content:encoded><![CDATA[<p>In einem <a title="selfoss phphatesme" href="http://www.phphatesme.com/blog/tools/tobias-zeisings-selfoss/">Gastbeitrag bei phphatesme</a> schreibe ich über <a title="selfoss" href="http://selfoss.aditu.de">selfoss</a>. Dort stelle ich auch die verschiedenen Bibliotheken vor, die ich für den RSS Reader verwende. Also für Interessierte: schaut einfach rein.</p>
<p>Herzlichen Dank an Nils, dass er mir die Möglichkeit gegeben hat, selfoss in seinem Blog vorzustellen.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aditu.de/2011/12/09/hintergrunde-zu-selfoss/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>selfoss 1.0 final</title>
		<link>http://blog.aditu.de/2011/11/13/selfoss-1-0-final/</link>
		<comments>http://blog.aditu.de/2011/11/13/selfoss-1-0-final/#comments</comments>
		<pubDate>Sun, 13 Nov 2011 15:20:08 +0000</pubDate>
		<dc:creator>Tobi</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Projekte]]></category>
		<category><![CDATA[selfoss]]></category>
		<category><![CDATA[Webentwicklung]]></category>

		<guid isPermaLink="false">http://blog.aditu.de/?p=892</guid>
		<description><![CDATA[So, endlich ist es vollbracht. selfoss 1.0 ist verfügbar. Dazu gibt es jetzt auch eine eigene Webseite, wo natürlich die Werbetrommel ordentlich angeheizt wird und mit Buzzwords nur so um sich geworfen wird. Neu verfügbar ist nun neben MySQL ein Datenbankbackend für Sqlite und MongoDB (danke Harald). Zudem habe ich noch ein paar Bugs entfernt. [...]]]></description>
			<content:encoded><![CDATA[<p>So, endlich ist es vollbracht. <a title="Selfoss" href="http://selfoss.aditu.de">selfoss 1.0</a> ist verfügbar. Dazu gibt es jetzt auch eine eigene <a title="Selfoss" href="http://selfoss.aditu.de/">Webseite</a>, wo natürlich die Werbetrommel ordentlich angeheizt wird und mit Buzzwords nur so um sich geworfen wird.</p>
<p><a href="http://selfoss.aditu.de"><img class="alignnone size-full wp-image-894" title="Selfoss Screenshot" src="http://blog.aditu.de/wp-content/uploads/2011/11/projects-selfoss.png" alt="" width="500" height="302" /></a></p>
<p>Neu verfügbar ist nun neben MySQL ein Datenbankbackend für Sqlite und MongoDB (danke <a title="Haralds Blog" href="http://phpblogger.de/">Harald</a>). Zudem habe ich noch ein paar Bugs entfernt. Vielen Dank an alle Betatester. Euer Feedback war echt super!</p>
<p>Auf <a href="http://selfoss.aditu.de">selfoss.aditu.de</a> ist nun auch eine Dokumentation zu finden. Dort ist auch eine kurze Erklärung, wie eigene spouts, also andere Anwendungen und Quellen an Selfoss angeschlossen werden können. Dazu habe ich <a title="Selfoss: Eigene Datenquellen erstellen" href="http://blog.aditu.de/2011/10/17/selfoss-eigene-datenquellen-erstellen/">hier im Blog</a> ja auch schon einmal ein Tutorial geschrieben.</p>
<p>Tja, sonst kann ich nur sagen: schaut euch selfoss einfach einmal an. Ich nutze es ja schon seit einigen Monaten und schätze die schlichte und übersichtliche Art, News zu lesen sehr.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aditu.de/2011/11/13/selfoss-1-0-final/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Selfoss: Eigene Datenquellen erstellen</title>
		<link>http://blog.aditu.de/2011/10/17/selfoss-eigene-datenquellen-erstellen/</link>
		<comments>http://blog.aditu.de/2011/10/17/selfoss-eigene-datenquellen-erstellen/#comments</comments>
		<pubDate>Mon, 17 Oct 2011 17:45:39 +0000</pubDate>
		<dc:creator>Tobi</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Projekte]]></category>
		<category><![CDATA[selfoss]]></category>
		<category><![CDATA[Webentwicklung]]></category>
		<category><![CDATA[datenquellen]]></category>
		<category><![CDATA[spouts]]></category>

		<guid isPermaLink="false">http://blog.aditu.de/?p=839</guid>
		<description><![CDATA[Letzte Woche habe ich ja den neuen RSS Reader selfoss als Beta Version veröffentlicht. Ein Vorteil von dem Reader ist die Erweiterbarkeit hinsichtlich der Quellen. So können nicht nur RSS Feeds verarbeitet, sondern auch beliebige Quellen angezapft werden (z.B. Logfiles, Email Accounts, Webseiten ohne RSS Feed, Facebook OpenGraph). Manchmal möchte man aber auch nur einzelne Einträge [...]]]></description>
			<content:encoded><![CDATA[<p>Letzte Woche habe ich ja den neuen RSS Reader selfoss als Beta Version <a title="selfoss 1.0 beta" href="http://blog.aditu.de/2011/10/02/selfoss-1-0-beta/">veröffentlicht</a>. Ein Vorteil von dem Reader ist die Erweiterbarkeit hinsichtlich der Quellen. So können nicht nur RSS Feeds verarbeitet, sondern auch beliebige Quellen angezapft werden (z.B. Logfiles, Email Accounts, Webseiten ohne RSS Feed, Facebook OpenGraph).</p>
<p>Manchmal möchte man aber auch nur einzelne Einträge von RSS Feeds um zusätzliche Informationen anreichern. Ich mache das beim RSS Feed von heise, wo der Inhalt des News Beitrages nicht mitgeliefert wird. Diesen lade ich dann einfach in einer speziellen Datenquelle, die sich um diese Funktion von einem gewöhnlichen RSS Feed unterscheidet, nach.</p>
<p>Nun gibt es eine Schritt-für-Schritt Anleitung, wie so eine Datenquelle erstellt werden kann.</p>
<h2>Eine Datenquelle, eine Klasse</h2>
<p>selfoss stellt ein kleines Framework zur Verfügung, das es erlaubt recht einfach neue Datenquellen hinzuzufügen. Dazu muss nur eine einzelne PHP Datei unter<br />
<code>/spouts/your_spouts/your_spout.php</code><br />
abgelegt werden (<code>your_spouts</code> und <code>your_spout</code> kann frei durch einen anderen Namen ersetzt werden). Diese PHP Datei muss eine einzelne Klasse enthalten, welche von der abstrakten Klasse <code>\spouts\spout</code> abgeleitet ist (man beachte, dass selfoss PHP 5.3 voraussetzt und \spouts der Namespace für alle Datenquellen ist).</p>
<h2>Datenelemente der Klasse</h2>
<p>Die eigene Klasse muss drei Datenelemente definieren:</p>
<ul>
<li><strong>name</strong>: der Name der Datenquelle</li>
<li><strong>description</strong>: eine Beschreibung</li>
<li><strong>params</strong>: hier werden die Optionen der Datenquelle festgelegt. Soll z.B. ein Benutzername eingegeben werden, so kann dies hier vorgegeben werden.</li>
</ul>
<p>Folgend gleich ein Beispiel für so eine Klasse. Natürlich fehlen hier noch die Methode, auf die ich gleich eingehe. Es wird eine Datenquelle für einen Email Account via IMAP definiert. Der Benutzer muss, wenn er eine solche neue Email IMAP Quelle definiert, die Email Adresse, das Passwort und den Server eintragen. <code>$params</code> beschreibt diese drei Parameter, legt fest, was für ein Typ diese darstellen und wie die Eingabe des Benutzers validiert wird.</p>
<pre class="brush: php; title: ; notranslate">
&lt;?PHP
namespace spouts\mail;
class imap extends \spouts\spout {
    public $name = 'Email';
    public $description = 'email imap account as source';
    public $params = array(
            &quot;email&quot; =&gt; array(
            &quot;title&quot;      =&gt; &quot;Email&quot;,
            &quot;type&quot;       =&gt; &quot;text&quot;,
            &quot;default&quot;    =&gt; &quot;&quot;,
            &quot;required&quot;   =&gt; true,
            &quot;validation&quot; =&gt; array(&quot;email&quot;)
        ),
        &quot;password&quot; =&gt; array(
            &quot;title&quot;      =&gt; &quot;Password&quot;,
            &quot;type&quot;       =&gt; &quot;password&quot;,
            &quot;default&quot;    =&gt; &quot;&quot;,
            &quot;required&quot;   =&gt; true,
            &quot;validation&quot; =&gt; array(&quot;notempty&quot;)
        ),
        &quot;host&quot; =&gt; array(
            &quot;title&quot;      =&gt; &quot;URL&quot;,
            &quot;type&quot;       =&gt; &quot;text&quot;,
            &quot;default&quot;    =&gt; &quot;&quot;,
            &quot;required&quot;   =&gt; true,
            &quot;validation&quot; =&gt; array(&quot;notempty&quot;)
        )
    );
}
</pre>
<h2>Methoden der Klasse</h2>
<p>Durch die abstrakte Elternklasse <code>\spouts\spout</code> muss die Datenquelle einige Funktionen implementieren. Diese werden dann im laufenden Betrieb von selfoss aufgerufen. Folgendes UML Diagramm gibt einen Überblick über die Struktur:</p>
<p><img class="alignnone size-full wp-image-867" title="selfoss spouts Klassendiagramm" src="http://blog.aditu.de/wp-content/uploads/2011/10/selfoss_spouts_klassendiagramm.png" alt="" width="500" height="437" /></p>
<p>Die Klasse muss drei Dinge implementieren:</p>
<ul>
<li>Sie muss eine Funktion <code>load($params)</code> für das Laden der Informationen zur Verfügung stellen. Diese wird während der Aktualisierung einmal aufgerufen und erhält als Parameter die aktuellen Einstellungen. <code>load($params)</code> muss von der Datenquelle implementiert werden und holt die Daten von der entfernten Quelle (z.B. führt einen IMAP Zugriff aus und lädt aktuelle Emails).</li>
<li>Sie muss das Interface <code>Iterable</code> implementieren. selfoss iteriert, nachdem <code>load()</code> ausgeführt wurde, dann über die einzelnen Einträge (mit Hilfe der Funktionen, die das Interface Iterable vorgibt: <code>rewind, current, key, next, valid</code>). Die einzelnen Einträge könnten z.B. neue Emails sein.</li>
<li>Während selfoss über die einzelnen Einträge iteriert, werden dann die Informationen dieser einzelnen Einträge abgerufen. Dies geschieht über Funktionen, welche durch die abstrakte Klasse <code>\spouts\spout</code> vorgegeben werden. Informationen sind z.B. Betreff einer Email, Email Body usw.</li>
</ul>
<p>Der Ablauf ist dann folgender:</p>
<ol>
<li>Im Beispiel würde <code>load($params)</code> von selfoss mit der vom Benutzer eingegebenen Email, Passwort und Host aufgerufen.</li>
<li>Diese Methode würde dann die Emails vom IMAP Account herunterladen und zwischenspeichern.</li>
<li>selfoss iteriert über die einzelnen Emails (mit <code>rewind, current, key, next, valid</code>).</li>
<li>Bei jedem einzelnen Iterationsschritt (also für jede Email) werden die Email-Informationen abgerufen (Inhalt, Betreff, Datum usw.) und zwar mit Hilfe der Funktionen: <code>getId(), getTitle(), getContent(), getIcon(), getLink(), getDate()</code>.</li>
<li>Um den Rest kümmert sich selfoss (prüfen ob es den Eintrag schon gibt, alte Einträge löschen usw.)</li>
</ol>
<p>Eine Implementierung für diese Funktionen liegt natürlich völlig in der Hand des Entwicklers einer Datenquelle. Daher verweise ich an dieser Stelle auf die vorhandenen Datenquellen. <code>\spouts\spout\feed (\spouts\rss\feed.php)</code> stellt ein gutes Beispiel dar. Wer diese als Vorlage nimmt, kommt recht schnell sehr weit, denn dort werden alle Funktionen genutzt. Soll nur ein Standard RSS Feed um Funktionen erweitert oder angepasst werden, dann verweise ich auch die Klasse <code>\spouts\spout\heise (\spouts\rss\heise.php)</code>. Hier wird lediglich die <code>getContent()</code> überschrieben und ansonsten verhält sich die Datenquelle wie ein gewöhnliches RSS Feed.</p>
<h2>Thumbnails</h2>
<p>Soll anstelle eines Textes ein Vorschaubild angezeigt werden, so muss die Methode <code>getThumbnail()</code> implementiert werden. Diese liefert für einen einzelnen Eintrag das Vorschaubildchen (die URL auf das Bild). <code>\spouts\spout\images (\spouts\rss\images.php)</code> ist ein Beispiel dafür. Diese Datenquelle geht von einem gewöhnlichen RSS Feed aus, durchsucht es nach Bilder (entweder ausgezeichnete Thumbnails im XML des Beitrages, oder das erste Bild im Content des Beitrages) und liefert die URL an selfoss. Das Laden, Verkleinern, Speichern und Aufräumen der Bilder übernimmt selfoss.</p>
<h2>Los gehts&#8230;</h2>
<p>Das war sie, die kurze und knackige Einführung, wie Datenquellen für selfoss entwickelt werden können. Gerne könnt ihr mir dazu Fragen stellen und bei Problemen schreiben (am besten hier im Blog, so dass auch andere von den Antworten profitieren können). Sehr freue ich mich auch über fertige Datenquellen. Gerne nehme ich neue in selfoss auf.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aditu.de/2011/10/17/selfoss-eigene-datenquellen-erstellen/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PDF Dateien mit Java rendern</title>
		<link>http://blog.aditu.de/2011/10/13/pdf-dateien-mit-java-rendern/</link>
		<comments>http://blog.aditu.de/2011/10/13/pdf-dateien-mit-java-rendern/#comments</comments>
		<pubDate>Thu, 13 Oct 2011 17:07:49 +0000</pubDate>
		<dc:creator>Tobi</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Webentwicklung]]></category>

		<guid isPermaLink="false">http://blog.aditu.de/?p=829</guid>
		<description><![CDATA[Besonders im Web-Umfeld ist das PDF Format ein beliebtes Mittel, da die Unterstützung durch Clients hervorragend ist. Häufig kommt man dann auch in die Verlegenheit mit PDF Dateien umzugehen und z.B. Dokumente on-the-fly zu erstellen oder zu editieren. In einem aktuellen Anwendungsfall sollen von PDF Dateien Vorschaubilder erzeugt und ausgegeben werden. Hierfür habe ich die [...]]]></description>
			<content:encoded><![CDATA[<p>Besonders im Web-Umfeld ist das PDF Format ein beliebtes Mittel, da die Unterstützung durch Clients hervorragend ist. Häufig kommt man dann auch in die Verlegenheit mit PDF Dateien umzugehen und z.B. Dokumente on-the-fly zu erstellen oder zu editieren. In einem aktuellen Anwendungsfall sollen von PDF Dateien Vorschaubilder erzeugt und ausgegeben werden.</p>
<p>Hierfür habe ich die hervorragende Java Bibliothek <a title="Pdf-renderer auf java.net" href="http://java.net/projects/pdf-renderer">Pdf-renderer</a> entdeckt. Die unter LGPL stehende OpenSource Library ermöglicht es, PDF Dateien zu rendern und als Bild auszugeben. Ursprünglich wurde die Bibliothek von Sun Labs entwickelt, welche einen PDF Viewer für ihre mit OpenOffice erzeugten Ausgaben benötigten. 2007, als der Pdf-renderer nicht mehr benötigt wurde, hat man sich entschlossen das Projekt als OpenSource Lösung zu veröffentlichen (<a title="JavaWorld" href="http://www.javaworld.com/javaworld/jw-06-2008/jw-06-opensourcejava-pdf-renderer.html">Quelle</a>).</p>
<h2>Einbinden</h2>
<p>Der Pdf-renderer kann einfach als Maven Dependency eingebunden oder als JAR Datei <a title="pdf-renderer download" href="http://java.net/projects/pdf-renderer/downloads">heruntergeladen</a> werden.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;dependency&gt;
	&lt;groupId&gt;org.swinglabs&lt;/groupId&gt;
	&lt;artifactId&gt;pdf-renderer&lt;/artifactId&gt;
	&lt;version&gt;1.0.5&lt;/version&gt;
&lt;/dependency&gt;
</pre>
<h2>PDF laden und Bild erzeugen</h2>
<p>Ein kurzes Codebeispiel zeigt, wie einfach aus einem PDF ein Bild erzeugt werden kann. In einem ersten Schritt wird aus der Datei als java.io.File Objekt ein ByteBuffer erzeugt. Dieser dient als Grundlage für den Zugriff auf den Inhalt der PDF Datei durch die pdf-renderer Klasse PDFFile.</p>
<pre class="brush: java; title: ; notranslate">
import com.sun.pdfview.PDFFile;
import com.sun.pdfview.PDFPage;
…
File file = new File(&quot;c:\\tmp\\test.pdf&quot;);
RandomAccessFile raf = new RandomAccessFile(file, &quot;r&quot;);
FileChannel channel = raf.getChannel();
ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY, 0,
channel.size());
PDFFile pdffile = new PDFFile(buf);
</pre>
<p>EIn PDFFile Objekt liefert Informationen über die PDF Datei (Metadaten, Anzahl Seiten usw.). In einem zweiten Schritt kann dann auf die einzelnen Seiten zugegriffen werden.</p>
<pre class="brush: java; title: ; notranslate">
int numPgs = pdffile.getNumPages();

PDFPage page = pdffile.getPage(0);
Rectangle rect = new Rectangle(
	0,
	0,
	(int) page.getBBox().getWidth(),
	(int) page.getBBox().getHeight()
);
Image img = page.getImage(rect.width, rect.height,
	rect,
	null, // null = kein ImageObserver
	true, // Hintergrund weiß
	true // synchron
);
</pre>
<p>Es wird die erste Seite geholt und ein Image aus der Java 2D API erzeugt. Dieses kann dann beliebig weiter verarbeitet werden.</p>
<p>Zum Download der Bibliothek: <a title="Pdf-renderer auf java.net" href="http://java.net/projects/pdf-renderer">http://java.net/projects/pdf-renderer</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aditu.de/2011/10/13/pdf-dateien-mit-java-rendern/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Modernizr: mit und ohne HTML5 &amp; CSS3</title>
		<link>http://blog.aditu.de/2011/06/17/modernizr-mit-und-ohne-html5-css3/</link>
		<comments>http://blog.aditu.de/2011/06/17/modernizr-mit-und-ohne-html5-css3/#comments</comments>
		<pubDate>Fri, 17 Jun 2011 17:19:17 +0000</pubDate>
		<dc:creator>Tobi</dc:creator>
				<category><![CDATA[Webentwicklung]]></category>

		<guid isPermaLink="false">http://blog.aditu.de/?p=734</guid>
		<description><![CDATA[Modernizr ist mittlerweile kein Geheimtipp mehr, nachdem ich es aber das erste Mal einsetze und das Skript überzeugen konnte, will ich es vorstellen. Das Prinzip von diesem JavaScript Skript ist recht simpel: Wo es geht, soll man aufgrund von Kompatibilität nicht auf neue Features von HTML5 und CSS3 verzichten. Aber es sollen auch nicht Besucher [...]]]></description>
			<content:encoded><![CDATA[<p><a title="modernizr" href="http://www.modernizr.com/">Modernizr</a> ist mittlerweile kein Geheimtipp mehr, nachdem ich es aber das erste Mal einsetze und das Skript überzeugen konnte, will ich es vorstellen.</p>
<p><a href="http://www.modernizr.com/"><img class="alignnone size-full wp-image-735" title="modernizer" src="http://blog.aditu.de/wp-content/uploads/2011/06/modernizer.png" alt="" width="200" height="44" /></a></p>
<p>Das Prinzip von diesem JavaScript Skript ist recht simpel: Wo es geht, soll man aufgrund von Kompatibilität nicht auf neue Features von HTML5 und CSS3 verzichten. Aber es sollen auch nicht Besucher ausgeschlossen werden, die nicht mit den neuesten Browser-Versionen ausgestattet sind (dabei denke ich nicht an IE6 Benutzer, sondern auch an alternative Browser; accessibility ist hier ein Thema). Die Idee ist also, dass Benutzer, welche mit aktueller Software eine Seite besuchen, alle Effekte und Funktionen zu sehen bekommen, wohingegen bei fehlenden Features einfach auf eine Fallbacklösung zurückgeschalten wird.</p>
<p>Ein Beispiel aus meinem aktuellen Projekt: Besitzt der Benutzer ein Touch-Device, dann werden zusätzliche Elemente geladen, wodurch ein Touch-Display besser unterstützt wird.</p>
<p>Dabei kann man sehr einfach feststellen, welche Features unterstützt werden. Modernizr setzt beim Aufruf der Seite für das html Element CSS Klassen, die beschreiben, was möglich ist und was nicht:</p>
<p><img class="alignnone size-full wp-image-738" title="modernizer-html" src="http://blog.aditu.de/wp-content/uploads/2011/06/modernizer-html.png" alt="" width="500" height="90" /></p>
<p>Zusätzlich steht auch ein JavaScript Objekt zur Verfügung. Aus meiner Sicht eine feine Sache. Manchmal kann man durchaus auf die neuen Features verzichten und dann ist Modernizr eine ganz gute Lösung.</p>
<p><a href="http://www.modernizr.com/">http://www.modernizr.com/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aditu.de/2011/06/17/modernizr-mit-und-ohne-html5-css3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iScroll 4</title>
		<link>http://blog.aditu.de/2011/06/05/iscroll-4/</link>
		<comments>http://blog.aditu.de/2011/06/05/iscroll-4/#comments</comments>
		<pubDate>Sun, 05 Jun 2011 10:18:09 +0000</pubDate>
		<dc:creator>Tobi</dc:creator>
				<category><![CDATA[Webentwicklung]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[inline scroll]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[iScroll]]></category>

		<guid isPermaLink="false">http://blog.aditu.de/?p=727</guid>
		<description><![CDATA[Mit dem Boom der Smartphones und Tablet kommt man beim Entwickeln von Webseiten natürlich mittlerweile nicht mehr um das Thema herum. Ein Problem, das dabei immer wieder auftaucht, ist das Scrollen innerhalb von Elementen fester Größe. Eine super Lösung, die sowohl unter iOS als auch Android läuft, ist iScroll. Auf meinem Android Phone läuft es [...]]]></description>
			<content:encoded><![CDATA[<p>Mit dem Boom der Smartphones und Tablet kommt man beim Entwickeln von Webseiten natürlich mittlerweile nicht mehr um das Thema herum. Ein Problem, das dabei immer wieder auftaucht, ist das Scrollen innerhalb von Elementen fester Größe.</p>
<p>Eine super Lösung, die sowohl unter iOS als auch Android läuft, ist <a title="iScroll 4" href="http://cubiq.org/iscroll-4">iScroll</a>. Auf meinem Android Phone läuft es zwar nicht besonders smooth (scheinbar ist es doch etwas anspruchsvoller, was die Ressourcen angeht), aber auf dem iPad funktioniert es super. Vielleicht also ganz nützlich für den ein oder anderen Leser von diesem Blog: <a title="iScroll 4" href="http://cubiq.org/iscroll-4">zur Webseite von iScroll</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aditu.de/2011/06/05/iscroll-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>pugixml: xml mit C++ verarbeiten</title>
		<link>http://blog.aditu.de/2011/02/10/pugixml-xml-mit-c-verarbeiten/</link>
		<comments>http://blog.aditu.de/2011/02/10/pugixml-xml-mit-c-verarbeiten/#comments</comments>
		<pubDate>Thu, 10 Feb 2011 19:05:34 +0000</pubDate>
		<dc:creator>Tobi</dc:creator>
				<category><![CDATA[Webentwicklung]]></category>
		<category><![CDATA[bibliothek]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[mongoose]]></category>
		<category><![CDATA[pugixml]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.aditu.de/?p=702</guid>
		<description><![CDATA[Auf meiner Suche nach einem guten XML Parser, bin ich auf die sehr gute C++ Bibliothek pugixml gestoßen. Mit wenigen Zeilen Code, lassen sich XML Dateien parsen und verändern. pugixml ist dabei sehr schnell, da kein XML zuvor validiert wird, portabel und besteht lediglich aus zwei Sourcecode Dateien (Header und cpp Datei). Letzteres macht die [...]]]></description>
			<content:encoded><![CDATA[<p>Auf meiner Suche nach einem guten XML Parser, bin ich auf die sehr gute C++ Bibliothek <a title="pugixml" href="http://code.google.com/p/pugixml/">pugixml</a> gestoßen. Mit wenigen Zeilen Code, lassen sich XML Dateien parsen und verändern. <a title="pugixml" href="http://code.google.com/p/pugixml/">pugixml</a> ist dabei sehr schnell, da kein XML zuvor validiert wird, portabel und besteht lediglich aus zwei Sourcecode Dateien (Header und cpp Datei). Letzteres macht die Integration in eigene Projekte sehr leicht.</p>
<p>Ein String kann ganz einfach mit folgenden Zeilen geparsed werden:</p>
<pre class="brush: cpp; title: ; notranslate">
std::string source(
 &quot;&lt;test&gt;&quot;
 &quot;&lt;eintrag id=\&quot;1\&quot;&gt;bla&lt;/eintrag&gt;&quot;
 &quot;&lt;eintrag id=\&quot;2\&quot;&gt;bla2&lt;/eintrag&gt;&quot;
 &quot;&lt;/test&gt;&quot;);
pugi::xml_document doc;
pugi::xml_parse_result result =
     doc.load_buffer_inplace(
         (void*)(source.c_str()),
         source.length()
      );
</pre>
<p>Um beispielsweise einen Eintrag zu suchen, kann folgender Aufruf ausgeführt werden, wobei hier XPath verwendet wird:</p>
<pre class="brush: cpp; title: ; notranslate">
pugi::xpath_node_set entries =
    doc.select_nodes(&quot;/test/eintrag[@id='2']&quot;);
pugi::xml_node entry = entries[0].node();
std::cout &lt;&lt; entry[0].node().child_value(); // bla
</pre>
<p>Das node_set apps enthält dann alle gefundenen nodes, wobei über den [] Operator auf die einzelnen Elemente zugegriffen werden kann.</p>
<p>Einen guten Überblick bietet der <a href="http://pugixml.googlecode.com/svn/tags/latest/docs/quickstart.html">QuickStart-Guide</a> oder die sehr ausführliche und gute <a href="http://pugixml.googlecode.com/svn/tags/latest/docs/manual.html">Dokumentation</a>.</p>
<p><a title="pugixml" href="http://code.google.com/p/pugixml/">pugixml</a> steht unter der MIT Lizenz zur Verfügung und nach einem ersten Einsatz kann ich die Bibliothek nur empfehlen. Aus meiner Sicht ein echter Tipp, insbesondere, weil die Einbindung einfach und unkompliziert ist. <a title="pugixml" href="http://code.google.com/p/pugixml/">pugixml</a> hat mich von der hohen Qualität stark an <a href="http://blog.aditu.de/2010/05/15/serverbridge-zwischen-php-und-cc/">mongoose</a> erinnert.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aditu.de/2011/02/10/pugixml-xml-mit-c-verarbeiten/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend_Translate: Fallback für Übersetzungen</title>
		<link>http://blog.aditu.de/2011/02/01/zend_translate-fallback-fur-ubersetzungen/</link>
		<comments>http://blog.aditu.de/2011/02/01/zend_translate-fallback-fur-ubersetzungen/#comments</comments>
		<pubDate>Tue, 01 Feb 2011 17:06:08 +0000</pubDate>
		<dc:creator>Tobi</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Projekte]]></category>
		<category><![CDATA[rsslounge]]></category>
		<category><![CDATA[Webentwicklung]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[Zend_Translate]]></category>

		<guid isPermaLink="false">http://blog.aditu.de/?p=690</guid>
		<description><![CDATA[Häufig kommt es vor, dass Sprachdateien nicht vollständig sind. Ich habe den Effekt bei rsslounge, da ich hier von verschiedenen Personen Sprachdateien bekomme. Da ich nicht sicherstellen kann, ob auch wirklich jeder Key der Sprachdatei übersetzt wurde (außer ich prüfe manuell die gesamte Datei), bietet es sich an, einfach als Fallback-Lösung die entsprechende englische Übersetzung [...]]]></description>
			<content:encoded><![CDATA[<p>Häufig kommt es vor, dass Sprachdateien nicht vollständig sind. Ich habe den Effekt bei <a title="rsslounge free rss feed reader" href="http://rsslounge.aditu.de">rsslounge</a>, da ich hier von verschiedenen Personen Sprachdateien bekomme. Da ich nicht sicherstellen kann, ob auch wirklich jeder Key der Sprachdatei übersetzt wurde (außer ich prüfe manuell die gesamte Datei), bietet es sich an, einfach als Fallback-Lösung die entsprechende englische Übersetzung zu verwenden.</p>
<p><a title="Zend Framework Manual" href="http://framework.zend.com/manual/de/zend.translate.html">Zend_Translate</a> bietet hier eine einfache Möglichkeit &#8220;Routen&#8221; zu erstellen. Das heißt man kann festlegen, welche Sprache alternativ verwendet werden soll. Dabei können sogar Ketten gebildet werden (z.B. wenn Französisch nicht gefunden wurde, dann in der deutschen Übersetzung suchen und wenn dort auch nichts gefunden wird, in der englischen). Wobei sich mir der Sinn von so einer Verkettung nicht ganz erschließt.</p>
<p>Das setzen einer Route ist sehr einfach. Folgendes Beispiel scanned ein übergebenes Verzeichnis nach CSV Dateien und übernimmt deren Inhalt als Übersetzung. Mit dem Key &#8220;route&#8221; wird definiert, wie die Sprachen verkettet werden sollen. In diesem Beispiel ist Englisch die Fallbacksprache für Deutsch und Französisch.</p>
<pre class="brush: php; title: ; notranslate">
$language = new Zend_Translate(
            'csv',    // Typ der Quelle: hier csv Dateien
            'locale', // Quell-Verzeichnis
            'en',     // Standard Sprache
            array(    // Optionen
                'scan' =&gt; Zend_Translate::LOCALE_DIRECTORY,
                'route'     =&gt; array( 'de' =&gt; 'en', 'fr' =&gt; 'en' )
            ));
</pre>
<p>Der sauberste Weg ist es natürlich alle Schlüssel auf zu übersetzen. Beim Aufspüren von fehlenden Übersetzungen <a href="http://blog.aditu.de/2009/03/10/zend_translate-fehlende-ubersetzungen-loggen/">hilft Zend_Translate ebenfalls</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aditu.de/2011/02/01/zend_translate-fallback-fur-ubersetzungen/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>HeadJS &#8211; dynamisches Laden von JavaScript Dateien</title>
		<link>http://blog.aditu.de/2011/01/31/headjs-dynamisches-laden-von-javascript-dateien/</link>
		<comments>http://blog.aditu.de/2011/01/31/headjs-dynamisches-laden-von-javascript-dateien/#comments</comments>
		<pubDate>Mon, 31 Jan 2011 19:54:14 +0000</pubDate>
		<dc:creator>Tobi</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Projekte]]></category>
		<category><![CDATA[rsslounge]]></category>
		<category><![CDATA[Webentwicklung]]></category>
		<category><![CDATA[HeadJS]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://blog.aditu.de/?p=678</guid>
		<description><![CDATA[Ein Projekt, das schon länger auf der ToDo Liste steht, habe ich nun heute etwas genauer in Augenschein genommen: Bei HeadJS handelt es sich um ein kleines JavaScript Skript, welches in der Lage ist, weitere JavaScript Dateien nachzuladen: Der Vorteil ist die Tatsache, dass die weiteren Skriptdateien kontrolliert parallelisiert heruntergeladen werden. Wird dieser Aufruf am [...]]]></description>
			<content:encoded><![CDATA[<p>Ein Projekt, das schon länger auf der ToDo Liste steht, habe ich nun heute etwas genauer in Augenschein genommen:</p>
<p><a href="http://headjs.com/"><img class="alignnone size-full wp-image-679" title="head-js" src="http://blog.aditu.de/wp-content/uploads/2011/01/head-js.jpg" alt="" width="480" height="163" /></a></p>
<p>Bei <a href="http://headjs.com/">HeadJS</a> handelt es sich um ein kleines JavaScript Skript, welches in der Lage ist, weitere JavaScript Dateien nachzuladen:</p>
<pre class="brush: jscript; title: ; notranslate">
head.js(
 &quot;/path/to/jquery.js&quot;,
 &quot;/google/analytics.js&quot;,
 &quot;/js/site.js&quot;,
 function() {
     // all done
 }
);
</pre>
<p>Der Vorteil ist die Tatsache, dass die weiteren Skriptdateien kontrolliert parallelisiert heruntergeladen werden. Wird dieser Aufruf am Ende der Website durchgeführt (also vor dem schließenden body Tag), so kann die HTML Seite, sowie die Stylesheets ungehindert geladen und gerendert werden, bevor mit der Verarbeitung von JavaScript Dateien begonnen wird. Das Ergebnis: die Seite wird schneller angezeigt. Mit 2,3 kB ist das Skript auch schön kompakt und klein.</p>
<p>Weitere Features sind eine bessere HTML5 Kompatibilität, automatisch gesetzte CSS Klassen (z.B. für bestimmte Browser) und noch einige weitere Schmankerl. Es lohnt sich also das kleine Skript genauer anzusehen. Im Einsatz habe ich es bei <a href="http://rsslounge.aditu.de">rsslounge</a> (ab Version 1.7, die ich in wenigen Tagen online stellen will).</p>
<p>Zur headJS Webseite: <a href="http://headjs.com/">http://headjs.com/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aditu.de/2011/01/31/headjs-dynamisches-laden-von-javascript-dateien/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

