<?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>blog.dennis.io &#187; coding</title>
	<atom:link href="http://blog.dennis.io/category/coding/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.dennis.io</link>
	<description>... geek and proud of it</description>
	<lastBuildDate>Thu, 08 Dec 2011 18:34:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>phpUnit und Klassen mit __call</title>
		<link>http://blog.dennis.io/phpunit-und-klassen-mit-__call/</link>
		<comments>http://blog.dennis.io/phpunit-und-klassen-mit-__call/#comments</comments>
		<pubDate>Thu, 08 Dec 2011 18:34:18 +0000</pubDate>
		<dc:creator>dennis</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[phpunit]]></category>
		<category><![CDATA[__call]]></category>

		<guid isPermaLink="false">http://blog.dennis.io/?p=386</guid>
		<description><![CDATA[Nutzt man phpUnit mit Klassen die MagicMethods wie z.B. __call() enthalten ist Vorsicht geboten. Ich habe gerade recht lange gebraucht um herauszufinden, warum folgender Test nicht funktioniert. Zunächst zwei Klassen, eine davon definieren wir als abstract class: &#60;?php class AnotherRealObject { public function __call($method, $args) { return 'AnotherRealObject->'.$method.'()'; } } abstract class SomeAbstractClassWithConcreteMethods { private [...]]]></description>
			<content:encoded><![CDATA[<p>Nutzt man phpUnit mit Klassen die MagicMethods wie z.B. __call() enthalten ist Vorsicht geboten. Ich habe gerade recht lange gebraucht um herauszufinden, warum folgender Test nicht funktioniert.</p>

<p>Zunächst zwei Klassen, eine davon definieren wir als <em>abstract class</em>:</p>

<div><pre class="brush:php">
&lt;?php
    class AnotherRealObject {
    
        public function __call($method, $args) {
            return 'AnotherRealObject->'.$method.'()'; 
        }
    
    }

    abstract class SomeAbstractClassWithConcreteMethods {

        private $anotherObject;
    
        abstract public function abstractMethod();
    
       public function concreteMethodToSetObject($o) {
            $this->anotherObject = $o;
        }

        public function concreteMethod() {
            return $this->anotherObject->aMethod();
        }
    
    }        
?&gt;   
</pre></div>

<p><span id="more-386"></span>
Soweit nichts aufregendes. AnotherRealObject enthält lediglich eine Methode, die bei einem beliebigen Methoden-Aufruf einen String zurückgibt, der angibt welche Methode auf dem Objekt aufgerufen wurde. Mal kurz in einer interaktiven PHP-Shell getestet sieht das ganze so aus:</p>

<div><pre class="brush:bash">
    php > $stub = new AnotherRealObject();
    php > echo $stub->blubb();
    AnotherRealObject->blubb()
    php > echo $stub->someMethodWithAnArbitraryName();
    AnotherRealObject->someMethodWithAnArbitraryName()  
</pre></div>

<p>Die zweite Klasse ist abstract definiert. Das hat für diesen Beitrag keinen besonderen Grund, ich wollte in meinen Tests einfach nur ausschließen, dass das Problem darauf zurückzuführen ist. Die Klasse hat zwei konkrete Methoden. Eine zum Setzen der Abhängigkeit $anotherObject und eine weitere, die auf diesem Objekt eine Methode aufruft und deren Rückgabewert zurückgibt.</p>

<p>Ein phpUnit Test um die abstrakte Klasse zu testen könnte wie folgt aussehen:</p>

<div><pre class="brush:php">
    class phpUnitBugTest extends PHPUnit_Framework_TestCase {

        private $uut;
        private $stub;

        public function setUp() {

            $this->uut = $this->getMockForAbstractClass('SomeAbstractClassWithConcreteMethods');

            $this->stub = $this->getMock('AnotherRealObject');
            $this->stub->expects( $this->any() )
                          ->method('aMethod')
                       ->will ( $this->returnValue('StubOfAnotherRealObject->aMethod()') );

            $this->uut->concreteMethodToSetObject($this->stub);
        }


        public function testBug() {
            $this->assertEquals('StubOfAnotherRealObject->aMethod()', $this->uut->concreteMethod());
        }


    }
</pre></div>

<p>Mit der durch phpUnit bereitgestellten Methode <em>getMockForAbstractClass()</em> instanzieren wir eine Instanz der abstrakten Klasse (das Testobjekt). Außerdem instanzieren wir ein Stub von <em>AnotherRealObject</em> und legen fest, dass beim Aufruf der Methode <em>aMethod</em> auf diesem Stub der String <em>StubOfAnotherRealObject->aMethod()</em> zurückgegeben wird. Anschließend wird das Stub noch in die Instanz der abstrakten Klasse injected.</p>

<p>Soweit so gut &#8211; fehlt der eigentliche Test. Was sollte passieren, wenn auf dem TestObjekt die Methode <em>concreteMethod()</em> aufgerufen wird? Nun ja, die Methode ruft auf dem Feld $anotherObject die Methode <em>aMethod</em> auf. Dem Feld <em>$anotherObject</em> ist unser Stub zugewiesen und dem Stub haben wir gesagt, dass es beim Aufruf von <em>anotherMethod</em> den String <em>StubOfAnotherRealObject->aMethod()</em> zurückgeben soll. Dementsprechend sollte ein aufruf von <em>concreteMethod()</em> genau diesen String zurückliefern.</p>

<p>Leider spielt phpUnit hier nicht mit. Der Test schlägt fehl:</p>

<div><pre class="brush:bash">
    There was 1 failure:

    1) phpUnitBugTest::testBug
    Failed asserting that two strings are equal.
    --- Expected
    +++ Actual
    @@ @@
    -StubOfAnotherRealObject->aMethod()
    +

    dev/phpUnitBugTest.php:45   
</pre></div>

<p>Wie man sieht gibt es gar keinen Rückgabewert. 
Aber warum ist das so? PhpUnit erstellt nur Method-Stubs für Methoden, die es tatsächlich in der Klasse gibt. Die Methode <em>aMethod</em> gibt es aber nicht wirklich, also erstellt phpUnit auch kein Stub dafür. Es gibt allerdings eine einfache Lösung für das Problem &#8211; auch wenn ich sie nicht besonders schön finde: Man sagt phpUnit einfach explizit, dass es einen Stub für die Methode <em>aMethod</em> erstellen soll. Dies geschieht beim erzeugen des Stubs:</p>

<div><pre class="brush:php">
    $this->stub = $this->getMock('AnotherRealObject', array('aMethod'));
</pre></div>

<p>Mit dieser Änderung läuft der Test durch. Aber Vorsicht: PhpUnit erstellt jetzt nur Stubs, die durch den Parameter festgelegt wurden. D.h. es müssen alle Methoden in diesem Array übergeben werden, für die Subs angelegt werden sollen &#8211; egal ob diese in der eigentlichen Klassen existieren oder nicht. Und genau dies ist auch der Grund, warum ich diese Lösung nicht schön finde.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dennis.io/phpunit-und-klassen-mit-__call/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mockito und Maps</title>
		<link>http://blog.dennis.io/mockito-und-maps/</link>
		<comments>http://blog.dennis.io/mockito-und-maps/#comments</comments>
		<pubDate>Thu, 14 Apr 2011 14:21:54 +0000</pubDate>
		<dc:creator>dennis</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[compareTo]]></category>
		<category><![CDATA[equals]]></category>
		<category><![CDATA[hashCode]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[mockito]]></category>

		<guid isPermaLink="false">http://blog.dennis.io/?p=385</guid>
		<description><![CDATA[Ich schreibe gerade einige Tests für das Java Projekt meiner Master Arbeit. Dabei arbeite ich auch zum ersten Mal mit dem Mocking Framework Mockito. Im Zusammenhang mit Mockito musste ich eben einen wichtigen Unterschied zwischen einer HashMap und einer TreeMap lernen. Wenn man mit Mockito ein Objekt mockt, stellt das Framework automatisch stubs für equals() [...]]]></description>
			<content:encoded><![CDATA[<p>Ich schreibe gerade einige Tests für das Java Projekt meiner Master Arbeit. Dabei arbeite ich auch zum ersten Mal mit dem Mocking Framework <a href="http://mockito.org/" title="">Mockito</a>. Im Zusammenhang mit Mockito musste ich eben einen wichtigen Unterschied zwischen einer HashMap und einer TreeMap lernen.</p>

<p><span id="more-385"></span>
Wenn man mit Mockito ein Objekt mockt, stellt das Framework automatisch <a href="http://de.wikipedia.org/wiki/Stub_&#40;Programmierung&#41;" title="">stubs</a> für equals() und hashCode() bereit. Deshalb läuft folgender <a href="http://www.junit.org/" title="">JUnit</a> Test ohne Fehler durch:</p>

<div><pre class="brush:java">
@Test
public void testMockito() {

    BigDecimal o1 = mock(BigDecimal.class);
    BigDecimal o2 = mock(BigDecimal.class);

    assertEquals(false, o1.equals(o2));
}
</pre></div>

<p>Da Mockito sich also um equals() und hashCode() kümmert kann man ge&#8217;mockte Objekte auch einfach mit einer Map benutzen. Dazu zum Beispiel folgender Test:</p>

<div><pre class="brush:java">
@Test
public void testMockitoWithHashMap() {

    BigDecimal o1 = mock(BigDecimal.class);
    BigDecimal o2 = mock(BigDecimal.class);

    Map&lt;BigDecimal, String&gt; map = new HashMap&lt;BigDecimal, String&gt;();
    map.put(o1, &quot;erster Mock&quot;);

    assertEquals(true, map.containsKey(o1));
    assertEquals(false, map.containsKey(o2));   
}
</pre></div>

<p>Läuft. Super. Aber Vorsicht. Der gleiche Test mit einer TreeMap schlägt fehl:</p>

<div><pre class="brush:java">
@Test
public void testMockitoWithTreeMap() {

    BigDecimal o1 = mock(BigDecimal.class);
    BigDecimal o2 = mock(BigDecimal.class);

    Map&lt;BigDecimal, String&gt; map = new TreeMap&lt;BigDecimal, String&gt;();
    map.put(o1, &quot;erster Mock&quot;);

    assertEquals(true, map.containsKey(o1));
    assertEquals(false, map.containsKey(o2));   
}
</pre></div>

<p>So sieht die Fehlermeldung dazu aus:</p>

<div><pre class="brush:java">
java.lang.AssertionError: expected:&lt;false&gt; but was:&lt;true&gt;
    [...]
    at [...].testMockitoWithTreeMap(Test.java:92)
    [...]
</pre></div>

<p>Erfahrene Java Entwickler wissen natürlich sofort was hier los ist. Für alle anderen dürfte es nach einem Blick in die <a href="http://download.oracle.com/javase/6/docs/api/java/util/TreeMap.html#TreeMap&#40;&#41;" title="">API von TreeMap</a> klar werden:</p>

<blockquote>
  <p>Note that the ordering maintained by a sorted map (whether or not an explicit comparator is provided) must be consistent with equals if this sorted map is to correctly implement the Map interface. (See Comparable or Comparator for a precise definition of consistent with equals.) This is so because the Map interface is defined in terms of the equals operation, but a map performs all key comparisons using its compareTo (or compare) method, so two keys that are deemed equal by this method are, from the standpoint of the sorted map, equal. The behavior of a sorted map is well-defined even if its ordering is inconsistent with equals; it just fails to obey the general contract of the Map interface.</p>
</blockquote>

<p>Was bedeutet dies für das Mocking mit Mockito? Beim Aufruf von <em>map.containsKey(o2)</em> im letzten Test oben, wird intern irgendwann <em>o2.compareTo(o1)</em> aufgerufen. Im Interface <em>java.lang.Comparable</em> ist die Methode wie folgt definiert:</p>

<div><pre class="brush:java">int compareTo(T o)</pre></div>

<blockquote>
  <p>Compares this object with the specified object for order. Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.</p>
</blockquote>

<p>Da Mockito versucht sinnvolle Rückgabewerte zu erzeugen, wird der Aufruf von <em>o2.compareTo(o1)</em> &#8220;0&#8243; zurückgeben. 0 bedeutet aber in diesem Fall das o1 und o2 gleich sind. Deshalb liefert der Aufruf von <em>map.containsKey(o2)</em> auch ein <strong><em>true</em></strong>.</p>

<p>Ein kleiner Test dazu:</p>

<div><pre class="brush:java">
@Test
public void testMockitoWithTreeMapAndVerifyCompareToCall() {

    BigDecimal o1 = mock(BigDecimal.class);
    BigDecimal o2 = mock(BigDecimal.class);

    Map&lt;BigDecimal, String&gt; map = new TreeMap&lt;BigDecimal, String&gt;();
    map.put(o1, &quot;erster Mock&quot;);

    assertEquals(true, map.containsKey(o1));

    verify(o2, times(0)).compareTo(o1);
    map.containsKey(o2);
    verify(o2, times(1)).compareTo(o1);
}
</pre></div>

<p>Mit diesem Wissen können wir den Test von weiter oben umschreiben, so dass auch dieser durchläuft:</p>

<div><pre class="brush:java">
@Test
public void testMockitoWithTreeMap() {

    BigDecimal o1 = mock(BigDecimal.class);
    BigDecimal o2 = mock(BigDecimal.class);

    when(o2.compareTo(o1)).thenReturn(1); // NEU

    Map&lt;BigDecimal, String&gt; map = new TreeMap&lt;BigDecimal, String&gt;();
    map.put(o1, &quot;erster Mock&quot;);

    assertEquals(true, map.containsKey(o1));
    assertEquals(false, map.containsKey(o2));   
} 
</pre></div>

<p>Mit nur einer neuen Zeile läuft der Test von vorhin nun korrekt durch. Der Aufruf von <em>o2.compareTo(o1)</em> liefert nun 1, was bedeutet das o2 &#8220;größer&#8221; ist als o1 und somit nach o1 in der TreeMap eingeordnet wird.</p>

<h3>Fazit</h3>

<p>Für erfahrene Java Entwickler ist dieser Post mit Sicherheit nichts Neues und so wie ich das Problem hier beschrieben habe, ist der Fehler auch sofort ersichtlich. Wenn man allerdings eine Klasse testet die intern eine TreeMap benutzt, nach außen aber nur das Map Interface sichtbar macht, ist ein solcher Fehler nicht gleich ersichtlich und vielleicht verwirrend.</p>

<p>Neben der Erkenntnis über die Implementierungs-Unterschiede zwischen HashMap und TreeMap hat mir dieses Problem heute mal wieder gezeigt, wie wichtig und sinnvoll Testing ist. Durch das Schreiben dieses einen Tests habe ich ein neues Detail der Java API kennengelernt, mich näher mit Mocktio beschäftigt und gleich zwei Probleme in meinen eigenen Klassen gefunden und beseitigen können. So muss das sein! <img src='http://blog.dennis.io/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dennis.io/mockito-und-maps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>#gddde Mitbringsel: Spring Roo + GWT</title>
		<link>http://blog.dennis.io/gddde-mitbringsel-spring-roo-gwt/</link>
		<comments>http://blog.dennis.io/gddde-mitbringsel-spring-roo-gwt/#comments</comments>
		<pubDate>Wed, 10 Nov 2010 17:20:37 +0000</pubDate>
		<dc:creator>dennis</dc:creator>
				<category><![CDATA[GWT]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Spring Roo]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[gwt]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[springroo]]></category>

		<guid isPermaLink="false">http://blog.dennis.io/?p=384</guid>
		<description><![CDATA[Ich war gestern zusammen mit @marcwerner auf dem Google Developer Day in München. Sehr nette Veranstaltung von Google, auf der Vorträge zu Google Technologien gehalten werden und es lecker Essen gibt . Im ersten Vortrag den ich mir angehört habe ging es um Spring Roo und das Google Web Toolkit. Sehr spannende Sache, da ich [...]]]></description>
			<content:encoded><![CDATA[<p>Ich war gestern zusammen mit <a href="http://twitter.com/#!/marcwerner">@marcwerner</a> auf dem <a href="http://www.google.com/intl/de_ALL/events/developerday/2010/munich/index.html" title="Google Developer Day 2010">Google Developer Day in München</a>. Sehr nette Veranstaltung von Google, auf der Vorträge zu Google Technologien gehalten werden und es lecker Essen gibt <img src='http://blog.dennis.io/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Im ersten Vortrag den ich mir angehört habe ging es um <a href="http://www.springsource.org/roo" title="Spring Roo | SpringSource.org">Spring Roo</a> und das <a href="http://code.google.com/webtoolkit/" title="Google Web Toolkit - Google Code">Google Web Toolkit</a>. Sehr spannende Sache, da ich zur Entwicklung von WebApps sowieso vorhatte von PHP auf Java zu wechseln. Den Vortrag hielt <a href="http://www.springsource.com/people/cdupuis" title="Christian Dupuis | SpringSource">Christian Dupuis</a> von SpringSource. In seiner Demo zeigte er, wie man mit Spring Roo in unter 3 Minuten eine lauffähige WebApp zusammenbaut. Grund genug für mich mir das heute mal selbst anzuschauen und auszuprobieren.</p>

<p><span id="more-384"></span>
Zunächst erstmal alle Tools herunterladen, installieren und konfigurieren. Ich habe mir die <a href="http://www.springsource.com/landing/best-development-tool-enterprise-java" title="Development Tool Suite for Enterprise Java | SpringSource">SpringSource Tool Suite</a> heruntergeladen. Da ist alles dabei, sowohl Spring Roo, als auch <a href="http://maven.apache.org/" title="Maven - 
    Welcome to Apache Maven">Maven</a> und ein Spring Source Server zum lokalen Testen der Anwendungen. Nach dem Entpacken habe ich alles nach ~/Applications/ kopiert (Achtung, das ist kein Standard-Ordner unter OSX &#8211; den habe ich mir für lokale Anwendungen angelegt). Damit man Roo und Maven einfacher benutzen kann, muss das ganze noch in den Pfad aufgenommen werden. Dazu linke ich die Skripte einfach nach /usr/bin:</p>

<div><pre class="brush:bash">
    sudo ln -s /Users/dennis/Applications/roo-1.1.0/bin/roo.sh /usr/bin/roo
    sudo ln -s /Users/dennis/Applications/maven-2.2.1.RELEASE/bin/mvn /usr/bin/mvn
</pre></div>

<p>Achtung, die Pfade könnten bei dir etwas anders sein! Nicht einfach copy/pasten.</p>

<p><a href="http://dl.kips-world.de/misc/sts-dashboard.PNG"><img src="http://blog.dennis.io/thumb.php?file=http://dl.kips-world.de/misc/sts-dashboard.PNG" alt="sts-dashboard" /></a></p>

<p>Im Anschluss habe ich erstmal die SpringSource Tool Suite (STS) gestartet und im Willkommens-Bildschirm über &#8220;Install Extension&#8221; den Support für GWT installiert. Danach möchte STS einmal neu gestartet werden und dann kanns auch schon losgehen. Natürlich kann man jetzt einfach die IDE benutzen und das erste Spring Roo Projekt erstellen, aber ich wollte die Roo Konsole testen &#8211; über die IDE kann das ja jeder <img src='http://blog.dennis.io/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>

<p>Also wieder zurück auf die Konsole, ein neues Verzeichnis im Workspace anlegen und die roo-Shell aufrufen:</p>

<div><pre class="brush:bash">
    cd ~/springroo
    mkdir testApp
    cd testApp
    roo
</pre></div>

<p><a href="http://dl.kips-world.de/misc/roo-console.PNG"><img src="http://blog.dennis.io/thumb.php?file=http://dl.kips-world.de/misc/roo-console.PNG" alt="roo-console" /></a></p>

<p>In der roo-Shell habe ich folgende Befehle ausgeführt:</p>

<div><pre class="brush:bash">
    project --topLevelPackage io.dennis.roo.amawish
    persistence setup --provider HIBERNATE --database HYPERSONIC_IN_MEMORY 
    entity --class ~.domain.Item
    field string --fieldName label
    entity --class ~.domain.Account
    field string --fieldName email
    field set --fieldName items --element ~.domain.Item
    gwt setup
    perform eclipse
    perform clean
</pre></div>

<p>Die Befehle kannst du auch als <a href="http://dl.kips-world.de/misc/setup.roo" title="">roo-Script herunterladen</a> und ausführen. Das Skript einfach in das testApp Verzeichnis kopieren und dann in der <strong>roo-Shell</strong> folgenden Befehl ausführen:</p>

<div><pre class="brush:bash">
    script --file setup.roo
</pre></div>

<p>Wenn das Skript durchgelaufen ist (kann einen Moment dauern) kann man das Projekt am schnellsten über Maven starten. Dazu die roo-Shell verlassen (Command: quit) und Maven seine Arbeit machen lassen:</p>

<div><pre class="brush:bash">
    mvn gwt:run
</pre></div>

<p><a href="http://dl.kips-world.de/misc/roo-maven-gwt.PNG"><img src="http://blog.dennis.io/thumb.php?file=http://dl.kips-world.de/misc/roo-maven-gwt.PNG" alt="roo-maven-gwt" /></a></p>

<p>Jetzt kann man das Projekt im Browser aufrufen. Bei mir sieht das ganze so aus:</p>

<p><a href="http://dl.kips-world.de/misc/roo-gwt-example-application.PNG"><img src="http://blog.dennis.io/thumb.php?file=http://dl.kips-world.de/misc/roo-gwt-example-application.PNG" alt="roo-gwt-example-application" /></a></p>

<p>Das ging schnell oder? Wenn man jetzt an dem Projekt weiterarbeiten möchte kann man es ganz einfach in STS importieren (&#8220;File&#8221; > &#8220;Import&#8221; > &#8220;Existing Projects into Workspace&#8221;).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dennis.io/gddde-mitbringsel-spring-roo-gwt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP Getter/Setter Generator</title>
		<link>http://blog.dennis.io/php-gettersetter-generator/</link>
		<comments>http://blog.dennis.io/php-gettersetter-generator/#comments</comments>
		<pubDate>Sat, 30 Oct 2010 13:10:29 +0000</pubDate>
		<dc:creator>dennis</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[getter]]></category>
		<category><![CDATA[setter]]></category>

		<guid isPermaLink="false">http://blog.dennis.io/?p=381</guid>
		<description><![CDATA[Ich benutze seit kurzem die PHP Development Tools von Eclipse zum Entwickeln von PHP Code. Eclipse selbst ist eine sehr gute IDE, allerdings hat das PDT Plugin hier und da doch noch einige Schwächen. Zum Beispiel war ich gerade dabei, eine neue Klasse für das IRD Bogenoffset Tool zu schreiben, die insgesamt auf 52 Felder [...]]]></description>
			<content:encoded><![CDATA[<p>Ich benutze seit kurzem die <a href="http://www.eclipse.org/pdt/">PHP Development Tools</a> von <a href="http://www.eclipse.org/" title="Eclipse.org home">Eclipse</a> zum Entwickeln von PHP Code. Eclipse selbst ist eine sehr gute IDE, allerdings hat das PDT Plugin hier und da doch noch einige Schwächen. Zum Beispiel war ich gerade dabei, eine neue Klasse für das <a href="http://ird-online.de/wissen/ird-online-prozessrating/">IRD Bogenoffset Tool</a> zu schreiben, die insgesamt auf 52 Felder kam. Jetzt bin ich es von Java natürlich gewohnt, dass die IDE mir für diese Felder automatisch Getter und Setter generiert &#8211; leider geht das mit den PDT nicht <img src='http://blog.dennis.io/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> .</p>

<p>Nach einer kurzen Google Recherche musste ich feststellen, dass im Netz auch kein brauchbarer PHP Getter/Setter Generator aufzutreiben ist. Also, nicht lange rumdümpeln, schreibe ich mir halt schnell selbst einen &#8211; sowieso die Gelegenheit sich mal die <a href="http://php.net/manual/en/book.reflection.php" title="PHP: Reflection - Manual">PHP Reflection API</a> anzuschauen. Hier das Ergebnis nach 10 Minuten Arbeit:</p>

<div><pre class="brush:php">
#!/usr/bin/php
&lt;?php

    if (!is_file($argv[2])) 
        die('Use this way: '.$argv[0].' &lt;class_name&gt; &lt;path_to_your_class`s_php_file&gt;'."\n");

    require_once($argv[2]);

    $class = new $argv[1]();
    $reflection = new ReflectionClass($argv[1]);
    $fields = $reflection->getProperties(
        ReflectionProperty::IS_PRIVATE
        | ReflectionProperty::IS_PROTECTED
    );

    foreach ($fields AS $f) {

        // getter
        echo 'public function get'.ucfirst($f->getName()).'() {'."\n";
        echo "\t".'return $this->'.$f->getName().';'."\n";
        echo '}'."\n";
        // setter
        echo 'public function set'.ucfirst($f->getName()).'($val) {'."\n";
        echo "\t".'$this->'.$f->getName().' = $val;'."\n";
        echo '}'."\n\n";

    }
    echo 'Generated Getter and Setter for '.count($fields).' fields'."\n\n";
?&gt;   
</pre></div>

<p>Das ganze ist ein PHP-Konsolenscript. Als Parameter den Namen eurer Klasse und den Pfad zur PHP Datei mitgeben in der die Klasse deklariert ist. Als Ausgabe erhält man die Getter- und Setter-Methoden für alle Felder, die als <code>private</code> oder <code>protected</code> deklariert sind. Vielleicht hat ja noch jemand anders Verwendung dafür &#8211; mir hats eine Menge Zeit gespart <img src='http://blog.dennis.io/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dennis.io/php-gettersetter-generator/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>WP: Email-Absender</title>
		<link>http://blog.dennis.io/wp-email-absender-aendern/</link>
		<comments>http://blog.dennis.io/wp-email-absender-aendern/#comments</comments>
		<pubDate>Thu, 08 Oct 2009 20:47:12 +0000</pubDate>
		<dc:creator>dennis</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wordpress-plugins]]></category>
		<category><![CDATA[action]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[getting started]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://blog.kips-world.de/?p=226</guid>
		<description><![CDATA[Ich habe heute angefangen die Kundendatenbank des IRD an WordPress anzukoppeln damit sich unsere Kunden direkt auf unserer Webseite anmelden können und sich nicht extra über WordPress registrieren müssen. Beim Testen der Funktionen hat mich der Absender der Passwort-Erinnerungs-Mails extrem gestört. WordPress benutzt hier standardmäßig den Namen &#8220;WordPress&#8221; und die Email-Adresse &#8220;wordpress@domain.tld&#8221; (wobei domain.tld natürlich [...]]]></description>
			<content:encoded><![CDATA[<p>Ich habe heute angefangen die Kundendatenbank des IRD an WordPress anzukoppeln damit sich unsere Kunden direkt auf unserer Webseite anmelden können und sich nicht extra über WordPress registrieren müssen. Beim Testen der Funktionen hat mich der Absender der <code>Passwort-Erinnerungs-Mails</code> extrem gestört. WordPress benutzt hier standardmäßig den Namen &#8220;WordPress&#8221; und die Email-Adresse &#8220;wordpress@domain.tld&#8221; (wobei domain.tld natürlich durch die Domain ersetzt wird auf der WordPress läuft).</p>

<p>Zum Glück muss man bei WordPress mit solchen Schönheitsfehlern nicht leben &#8211; ein kleines MiniPlugin genügt um seine eigene Email-Adresse und den Absendernamen festzulegen. Hier erstmal der Code:</p>

<div><pre class="brush:php">
&lt;?php
/*
Plugin Name: myemail
Plugin URI: http://blog.kips-world.de
Description: Some wordpress hacks for my website
Version: 1.0
Author: Dennis Saenger
Author URI: http://blog.kips-world.de
*/

function kip_from_mail($f) {

        $admin = get_userdata(1);
        return $admin->user_email;
}
function kip_from_name($f) {

        $admin = get_userdata(1);
        return $admin->display_name;
}
add_filter('wp_mail_from', 'kip_from_mail', 0, 1);
add_filter('wp_mail_from_name', 'kip_from_name', 0, 1);
?&gt;
</pre></div>

<p>Um den Absendernamen und die Emailadresse zu ändern benutze ich hier je einen WordPress-Filter. Immer wenn WordPress eine Email verschicken will, werden diese beiden Filter automatisch aufgerufen. Als Parameter übergibt WordPress die Default-Werte an die Funktionen. Bei <em>kip_from_mail()</em> übergibt WordPress &#8220;wordpress -ät- blog.kips-world.de&#8221;, bei <em>kip_from_name()</em> wird &#8220;WordPress&#8221; übergeben. Man könnte diese Werte jetzt modifizieren und zurückgeben, aber ich habe mich dafür entschieden einfach den Nickname und die Emailadresse des Admin als Absender zu nutzen. Ich ignoriere die Variablen (<em>$f</em>) in beiden Funktionen also einfach und hole mir mit der Funktion <em>get_userdata()</em> einfach die Werte des admin Users (der admin hat die User-ID <em>1</em>).</p>

<p>Um das ganze selbst auszuprobieren erstellst du in deinem WordPress-Pluginordner einfach eine Datei &#8220;myemail.php&#8221; und kopierst den obigen PHP-Code dort hinein. Im Admin-Bereich von WordPress wird es dann ein neues Plugin &#8220;myemail&#8221; geben. Dieses noch schnell aktivieren und schon sendet WordPress Emails mit einem schönen Absender!</p>

<p>Wer jetzt Lust bekommen hat selbst kleine Modifikationen an WordPress vorzunehmen findet im WordPress-Codex alles was er wissen muss. In der <a href="http://codex.wordpress.org/Plugin_API">Plugin-API</a> gibt es eine Einführung zu Filtern und Actions (die beiden Plugin-Schnittstellen von WordPress). In der <a href="http://codex.wordpress.org/Function_Reference">Function Reference</a> werden alle WordPress-Funktionen inklusive Beschreibung aufgelistet. Und auf der Homepage von <a href="http://adambrown.info/">Adam</a> findet man eine komplette <a href="http://adambrown.info/p/wp_hooks">Liste mit allen Filtern und Actions</a> (sehr wichtig!).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dennis.io/wp-email-absender-aendern/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>batch rename unter mac osx</title>
		<link>http://blog.dennis.io/batch-rename-mac-osx/</link>
		<comments>http://blog.dennis.io/batch-rename-mac-osx/#comments</comments>
		<pubDate>Sat, 12 Sep 2009 19:50:18 +0000</pubDate>
		<dc:creator>dennis</dc:creator>
				<category><![CDATA[apple]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[batch]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[regexp]]></category>
		<category><![CDATA[rename]]></category>
		<category><![CDATA[sed]]></category>

		<guid isPermaLink="false">http://blog.kips-world.de/?p=168</guid>
		<description><![CDATA[Ich hatte gerade das Problem, dass ich 94 Bilddateien umbenennen musste. Die Bilder hatten alle den Teilstring &#8220;bearb_#&#8221; oder &#8220;bearb_&#8221; im Namen und der sollte entfernt werden. Unter MacOSX gibt es dafür natürlich einige grafische Tools, nicht zuletzt den Automator. Dieser bennent auf Wunsch beliebig viele Dateien um, allerdings mit festem Namen und einer laufenden [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.kips-world.de/wp-content/uploads/2009/09/konsole.png" alt="konsole" title="konsole" width="128" height="128" class="alignleft size-full wp-image-172" />
Ich hatte gerade das Problem, dass ich 94 Bilddateien umbenennen musste. Die Bilder hatten alle den Teilstring &#8220;bearb_#&#8221; oder &#8220;bearb_&#8221; im Namen und der sollte entfernt werden.</p>

<p>Unter MacOSX gibt es dafür natürlich einige grafische Tools, nicht zuletzt den <code>Automator</code>. Dieser bennent auf Wunsch beliebig viele Dateien um, allerdings mit festem Namen und einer laufenden Nummer. Ich wollte die Namen meiner Bilder allerdings behalten und nur den störenden Teilstring entfernen.</p>

<p>Hier zeigt sich mal wieder warum ich meinen Mac so mag: Geniales GUI &#8211; aber unter der Haube ein Unix mit all seinen nützlichen Tools! Einen Teilstring aus allen Dateinamen eines Ordners zu entfernen ist für ein Unix und die Bash keine Herausforderung &#8211; dazu braucht man nur eine einzige Befehlszeile:</p>

<p><span id="more-168"></span>
<pre class="brush:bash">
for FILE in * ; do NEWFILE=<code>echo $FILE | sed -E 's/bearb_#?//g'</code> ; mv "$FILE" "$NEWFILE" ; done
</pre></p>

<p>Die Befehle im Detail:</p>

<ul>
    <li>
    <em>for FILE in *; do</em>: Eine For-Schleife die nacheinander alle Dateien im aktuellen Verzeichnis einliest und deren Dateinamen in der Variable $FILE spiechert.
    </li>
    <li>
    <em>NEWFILE=` &#8230; `</em>: Diese Anweisung führt eine neue Variable $NEWFILE ein und weist ihr die Ausgabe der Befehle zwischen den Anführungszeichen zu. Die schrägen Anführungszeichen haben die Besonderheit, dass der String zwischen ihnen als Unix-Befehl ausgeführt wird.
    </li>
    <li>
    <em>echo $FILE | sed -E &#8216;s/bearb_#?//g&#8217;</em>: echo $FILE gibt einfach nur den alten Dateinamen aus und die Pipe (der senkrechte Strich: | ) leitet die Ausgabe von <em>echo</em> auf den zweiten Befehl <em>sed</em> um.

<em>sed</em> kann mit Hilfe von Regulären Ausdrücken Zeichenketten bearbeiten. Der Parameter -E aktiviert die erweiterten Regulären Ausdrücke von sed. Das <em>s</em> vor dem ersten Schrägstrich weist <em>sed</em> an, den String zwischen den ersten beiden Schrägstrichen mit dem String zwischen dem 2. und 3. Schrägstrich zu ersetzen.

Der 2. String ist leer, was bedeutet, dass der mit dem 1. Regulären Ausdruck gefundene String einfach gelöscht wird. Der Reguläre Ausdruck ist einfach der Teilstring den ich entfernen muss. Das #-Zeichen kam in manchen Strings nicht vor. Damit der Reguläre Ausdruck Teilstrings in der Form &#8220;bearb_&#8221; und &#8220;bearb_#&#8221; findet, steht das ?-Zeichen hinter dem #-Zeichen. Ein ?-Zeichen bedeutet bei Regulären Ausdrücken, dass ein Zeichen genau 0- oder 1mal vorkommen darf.
    </li>
<li><em>done</em>: Das abschließende <em>done</em> beendet die for-Schleife.</li>
</ul>

<p>Problem gelöst &#8211; mit Unix Hausmitteln, ohne extra Tools! <img src='http://blog.dennis.io/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dennis.io/batch-rename-mac-osx/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>der apfelplanet #1</title>
		<link>http://blog.dennis.io/der-apfelplanet-1/</link>
		<comments>http://blog.dennis.io/der-apfelplanet-1/#comments</comments>
		<pubDate>Tue, 01 Sep 2009 23:01:28 +0000</pubDate>
		<dc:creator>dennis</dc:creator>
				<category><![CDATA[apfelplanet]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[me]]></category>

		<guid isPermaLink="false">http://blog.kips-world.de/?p=130</guid>
		<description><![CDATA[Ich habe mir vor einiger Zeit die Domain &#8220;apfelplanet.de&#8221; gesichert. Ich würde auf der Domain gerne ein neues Projekt starten: Einen Planet für Apple bezogene Blogs. Was ist überhaupt ein Planet? Das sagt Wikipedia dazu: Planet ist ein serverseitiger Feedreader für Aggregator-Dienste, der zur Zusammenfassung verschiedener Nachrichtenquellen auf Websites genutzt wird. [...] Im übertragenen Sinn [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://icons.kips-world.de/nuvola/128x128/apps/browser.png" class="alignleft" alt="" />
Ich habe mir vor einiger Zeit die Domain &#8220;apfelplanet.de&#8221; gesichert. Ich würde auf der Domain gerne ein neues Projekt starten: Einen <em>Planet</em> für Apple bezogene Blogs. Was ist überhaupt ein Planet? Das sagt Wikipedia dazu:</p>

<blockquote>Planet ist ein serverseitiger Feedreader für Aggregator-Dienste, der zur Zusammenfassung verschiedener Nachrichtenquellen auf Websites genutzt wird. [...]
Im übertragenen Sinn wird der Begriff allgemein für Websites verwendet, die mittels eines Feed-Aggregators verschiedene Nachrichtenquellen, vor allem Blogs, zusammenfassen.</blockquote>

<p>Der erste Schritt muss nun sein das ich mir ein Design überlege. Es soll etwas sehr einfaches sein, was aber andererseits auch an Apple erinnern darf. Ich denke ich werde mich an <a href="http://www.me.com">Me.com</a> orientieren. In die graue Leiste oben muss ein schönes Logo (ein Planet der nach einem Apfel aussieht wäre genial oder? <img src='http://blog.dennis.io/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> ).</p>

<p>Dannach muss ich mich auf die Suche nach ein paar Seiten machen die sich am Planet beteiligen möchten. Ich möchte keine Apple-News Seiten aufnehmen, es sollen rein private Blogs sein. In meinem Newsreader haben sich in letzter Zeit einige &#8220;Apple&#8221;-Blogs angesammelt. Wenn die Seite steht und der Feedreader auf dem Webserver läuft werde ich die Webmaster mal anschreiben.</p>

<p>Ich denke ich werde als Reader &#8220;<a href="http://www.planetplanet.org/">das Original</a>&#8221; einsetzen. Dafür brauche ich zwar Python auf dem Webserver, aber wenn man seinen eigenen Root-Server hat, ist das weniger ein Problem. Dann kann ich das nächste mal gleich über die Installation und Konfiguration des Planet bloggen &#8230;</p>

<p>Wer sich mal ein paar Beispiele anschauen möchte kann ich den <a href="http://planet.ubuntuusers.de">planet.ubuntuusers.de</a>, <a href="http://planet.gnome.org">planet.gnome.org</a> oder den <a href="http://www.planet-index.org/">planet-index</a> empfehlen.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dennis.io/der-apfelplanet-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>aptana &#8211; die web ide</title>
		<link>http://blog.dennis.io/aptana-die-web-ide/</link>
		<comments>http://blog.dennis.io/aptana-die-web-ide/#comments</comments>
		<pubDate>Wed, 26 Aug 2009 23:26:50 +0000</pubDate>
		<dc:creator>dennis</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[html/css]]></category>
		<category><![CDATA[javascript/jQuery]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[aptana]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[ide]]></category>

		<guid isPermaLink="false">http://blog.kips-world.de/?p=57</guid>
		<description><![CDATA[Viele Entwickler von Webanwendungen sind der Meinung ein einfacher Text-Editor reicht für die tägliche Arbeit. Für kleine Projekte oder um mal schnell eine Änderung zu machen stimmt das sicherlich, aber wenn es an größere Projekte geht erleichtert eine gute IDE die Arbeit erheblich. Ich arbeite schon seit längerem mit Aptana. Die Standard Version von Aptana [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.kips-world.de/wp-content/uploads/2009/08/logo.png" alt="aptana" title="aptana" width="54" height="53" class="alignright size-full wp-image-97" />
Viele Entwickler von Webanwendungen sind der Meinung ein einfacher Text-Editor reicht für die tägliche Arbeit. Für kleine Projekte oder um mal schnell eine Änderung zu machen stimmt das sicherlich, aber wenn es an größere Projekte geht erleichtert eine gute IDE die Arbeit erheblich.</p>

<p><span id="more-57"></span></p>

<p>Ich arbeite schon seit längerem mit <a href="http://aptana.com/">Aptana</a>. Die Standard Version von Aptana Studio ist kostenlos und bringt alle wichtigen Funktionen die ich benötige mit sich. Das schöne an Aptana, es basiert auf <a href="http://de.wikipedia.org/wiki/Eclipse_(IDE)">Eclipse</a> und ist als Standalone Anwendung aber auch als Eclipse Plugin zu haben. Da ich Eclipse sowieso auf dem Rechner habe, benutze ich die Plugin-Version von Aptana.</p>

<p>Die Plugin-Version von Aptana wird wie jede andere Erweiterung für Eclipse installiert. In der Eclipse IDE auf &#8220;Hilfe&#8221; > &#8220;Neue Software installieren&#8221; und die Aptana Update Seite hinzufügen. In den folgenden Dialogen sicherstellen, dass die Kästchen für Aptana Studio aktiviert sind &#8211; fertig.</p>

<p><a href="http://blog.kips-world.de/wp-content/uploads/2009/08/aptana1.png"><img src="http://blog.kips-world.de/wp-content/uploads/2009/08/aptana1-150x150.png" alt="aptana1" title="aptana1" width="150" height="150" class="alignleft size-thumbnail wp-image-101" /></a>
Wenn Aptana Studio installiert ist und Eclipse neu gestartet wurde, wird man mit einem neuen Fenster begrüßt. In diesem Fenster können weitere Aptana Plugins installiert werden. Ich habe hier <strong>Aptana PHP</strong>, <strong>jQuery Support</strong> und <strong>Subversive</strong> nachinstalliert. Der Aptana CSS und HTML Editor ist im Studio schon integriert.</p>

<p><a href="http://blog.kips-world.de/wp-content/uploads/2009/08/aptana2.png"><img src="http://blog.kips-world.de/wp-content/uploads/2009/08/aptana2-150x150.png" alt="aptana2" title="aptana2" width="150" height="150" class="alignright size-thumbnail wp-image-102" /></a>
Wenn alles fertig installiert ist sollte man noch ein paar Einstellungen machen. Unter den Eclipse Einstellungen findet man nun einen neuen Unterpunkt &#8220;Aptana&#8221;. In &#8220;Aptana&#8221; unter &#8220;Editoren&#8221; > &#8220;PHP&#8221; > &#8220;PHP Bibliotheken&#8221; kann man zunächst <a href="http://smarty.net/">Smarty</a> aktivieren und dann zusätzlich eigene Bibliotheken hinzufügen. Ich habe hier mein PHP Framework <a href="http://blog.kips-world.de/pew">pew</a> hinzugefügt. Die hier aktivierten Bibliotheken liest Apatana ein und bietet eine <a href="http://de.wikipedia.org/wiki/Autovervollständigen">Autovervollständigung</a> für die Befehle der Bibliotheken an. Für PHP, HTML und CSS macht Aptana das selbstverständlich schon standardmäßig.</p>

<p>So, jetzt kann es endlich losgehen. Über &#8220;Datei&#8221; > &#8220;Neu&#8221; > &#8220;Aptana Projekte&#8221; > &#8220;PHP Projekt&#8221; kann nun ein neues Aptana PHP Projekt gestartet werden! Demnächst werde ich dann noch beschreiben wie man das SVN Plugin Subversive richtig installiert und konfiguriert.</p>

<p>Wem der Funktionsumfang von Eclipse + Aptana immernoch nicht genug ist, der kann sich einmal auf <a href="http://www.eclipseplugincentral.com/">eclipseplugincentral.com</a> umschauen. Dort finden sich noch über 1000 andere Plugins für Eclipse! Wer was gutes findet darf mir gerne Bescheid sagen <img src='http://blog.dennis.io/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.dennis.io/aptana-die-web-ide/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

