<?xml version="1.0" encoding="UTF-8" ?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
<title type="html">Foobaz</title>
<subtitle type="html">- coding and other sweetnesses -</subtitle>
<link href="http://foobaz.free.fr/blog/feed.php?atom" rel="self" type="application/atom+xml"/>
<link href="http://foobaz.free.fr/blog/" rel="alternate" type="text/html"/>
<updated>2010-07-02T12:05:00+01:00</updated>
<id>urn:md5:b4bb4845ef67565e77ee60982a9dacca</id>
<generator uri="http://pluxml.org/">Pluxml </generator>
<entry>
	<title>Un switch annoté en Java</title> 
	<link href="http://foobaz.free.fr/blog/?article7/un-switch-annote-en-java"/>
	<id>urn:md5:5e09ebc1bebe8cc216ab617d7f694214</id>
	<updated>2010-07-02T12:05:00+01:00</updated>
	<author><name>bastien</name></author>
	<dc:subject>Java</dc:subject>
	<content type="html">Un billet sur le blog de &lt;a href=&quot;http://agilitateur.azeau.com/post/2010/07/01/Un-switch-%C3%A9volutif-en-C&quot;&gt;l&#039;Agilitateur&lt;/a&gt; répondant à un billet sur le blog &lt;a href=&quot;http://blog.excilys.com/2010/06/25/de-switcher-nest-pas-jouer&quot;&gt;d&#039;Excilys&lt;/a&gt; concernant les switchs en java me donne envie de parler un peu de codage en Java. Cet article est une variante du code C# proposé par Oaz en Java.&lt;p&gt;Je vais vous épargner toute la discussion sur le switch c&#039;est bien / c&#039;est nul, il y a déjà les &lt;a href=&quot;http://blog.excilys.com/2010/06/25/de-switcher-nest-pas-jouer/comment-page-1/&quot;&gt;commentaires enflammés&lt;/a&gt; sur le blog d&#039;Excilys pour ça.&lt;/p&gt;
&lt;p&gt;
Passons directement au code : de la même manière qu&#039;Oaz l&#039;a fait, je dispose d&#039;une interface Function qui définit le contrat que vont suivre les différents cas du switch. Pour que l&#039;on sache que les différentes sous-classes sont bien des cases, on les annote avec un @Case créé pour l&#039;occasion :
&lt;pre class=&quot;brush: java;&quot;&gt;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Case {
	String name();
}
&lt;/pre&gt;
On demande au compilateur de garder cette annotation au runtime (pour faire du scanning dynamique), et on précise qu&#039;elle peut s&#039;appliquer à un type (classe ou interface).
&lt;/p&gt;

&lt;p&gt;On peut alors utiliser l&#039;annotation de cette façon :
&lt;pre class=&quot;brush: java;&quot;&gt;
public interface Function {
	void doYourJob();
}

@Case(name=&quot;bar&quot;)
public class BarFunction implements Function {

	public void doYourJob() {
		System.out.println(&quot;On va manger... des chips ! T&#039;entends ? DES CHIPS !!&quot;);
	}
}

@Case(name=&quot;foo&quot;)
public class FooFunction implements Function {

	public void doYourJob() {
		System.out.println(&quot;Hi, my name is foo!&quot;);
	}
}

@Case(name=&quot;othercase&quot;)
public class OtherCase {

	public void doYourJob() {
		System.out.println(&quot;I&#039;m not gonna be called :-(&quot;);
	}
}

&lt;/pre&gt;
&lt;/p&gt;

&lt;p&gt;Reste maintenant le plus dur à faire : scanner un package à la recherche de classes annotées @Case et qui héritent de notre classe de base (ici Function, mais on va essayer de rester génériques).

&lt;pre class=&quot;brush: java;&quot;&gt;
public class Switch&amp;lt;T&amp;gt; {

	private String packageName;
	private Map&amp;lt;String, T&amp;gt; cases;
	private Class&amp;lt;T&amp;gt; parentType;
	
	public Switch(String packageName, Class&amp;lt;T&amp;gt; parentType) {
		this.packageName = packageName;
		this.parentType = parentType;
		scanCases();
	}

	private void scanCases() {
		cases = new HashMap&amp;lt;String, T&amp;gt;();

		try {
			for (Class clazz : getClasses(packageName)) {
				if (clazz.isAnnotationPresent(Case.class) &amp;&amp; isA(clazz, parentType)) {
					Case theCase = (Case) clazz.getAnnotation(Case.class);
					cases.put(theCase.name(), (T) clazz.newInstance());
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		System.out.println(&quot;Scanned &quot; + cases.size() + &quot; cases.&quot;);
	}

	private boolean isA(Class clazz, Class&amp;lt;T&amp;gt; class1) {
		if (clazz.getSuperclass() == class1) {
			return true;
		}
		for (Class intf : clazz.getInterfaces()) {
			if (intf == class1) {
				return true;
			}
		}
		return false;
	}

	public T on(String caseName) throws IllegalArgumentException {
		if (cases.containsKey(caseName)) {
			return cases.get(caseName);
		} else {
			throw new IllegalArgumentException(&quot;The case &quot; + caseName + &quot; does not exist&quot;);
		}
	}

	private List&amp;lt;Class&amp;gt; getClasses(String pckgname) { ... }
&lt;/pre&gt;
J&#039;ai fait appel au &lt;a href=&quot;http://java.sun.com/j2se/1.5.0/docs/guide/language/generics.html&quot;&gt;generic type&lt;/a&gt; introduit en Java5, cela permet d&#039;avoir un switch acceptant n&#039;importe quelle classe de base qu&#039;implémentent les différents cas. J&#039;ai été obligé de repasser cette information dans le constructeur car en Java il n&#039;est pas possible de faire un T.class dans la phase de scan des classes (pour savoir si la classe scannée étend ou implémente T). À la place, on a donc un Class&lt;T&gt; en second paramètre.&lt;/p&gt;
&lt;p&gt;La méthode scanCases va parcourir toutes les classes d&#039;un package (grâce à la méthode getClasses() honteusement &lt;a href=&quot;http://forums.sun.com/thread.jspa?messageID=3946549#3946549&quot;&gt;trouvée sur le forum de &lt;strike&gt;Sun&lt;/strike&gt; Oracle&lt;/a&gt;). Pour chaque classe, on regarde si elle est annotée @Case et si elle étend ou implémente T. Si c&#039;est le cas, on en ajoute une instance dans une Map avec le nom du cas comme clé.&lt;/p&gt;
&lt;p&gt;Dernière étape : la méthode on() qui renvoie l&#039;instance associée à un cas ou jette une exception s&#039;il n&#039;existe pas.&lt;/p&gt;
&lt;p&gt;La glue entre tout ça, c&#039;est un main assez simple : 
&lt;pre class=&quot;brush: java;&quot;&gt;
public class Main {

	public static void main(String[] args) {
		Switch&amp;lt;Function&amp;gt; swi = new Switch&amp;lt;Function&amp;gt;(&quot;com.jansen.annotatedswitch.demo&quot;, Function.class);
		
		swi.on(&quot;foo&quot;).doYourJob();
		swi.on(&quot;bar&quot;).doYourJob();
		swi.on(&quot;othercase&quot;).doYourJob();
	}

}
&lt;/pre&gt;
Notez le dernier appel qui va planter : j&#039;ai bien une classe annotée @Case(name=&quot;othercase&quot;) mais elle n&#039;implémente pas Function (une ruse de sioux pour égarer le lecteur peu attentif ;-) ).&lt;/p&gt;

&lt;p&gt;Conclusion : c&#039;est aussi possible en Java, avec un peu de gymnastique intellectuelle pour arriver à faire ce qu&#039;on souhaite avec les generics :P&lt;/p&gt;</content>
</entry>
<entry>
	<title>Le logger de la mort</title> 
	<link href="http://foobaz.free.fr/blog/?article6/le-logger-de-la-mort"/>
	<id>urn:md5:7b115a2c1463228a1979ed82db28e683</id>
	<updated>2010-02-04T16:24:00+01:00</updated>
	<author><name>bastien</name></author>
	<dc:subject>Java</dc:subject>
	<content type="html">&lt;p&gt;Parfois, au cours d&#039;une mission chez un client, on tombe sur du code pas testé, et pas toujours prévu pour être testé non plus. Je vais présenter un cas sur lequel je suis tombé récemment, issu d&#039;un assez gros projet Java EE en cours de développement.&lt;/p&gt;Une classe de services X effectue une certain nombre de traitements. En cas d&#039;erreur, au lieu de jeter une exception métier, un code d&#039;erreur est loggué. Impossible d&#039;utiliser un &lt;code&gt;@Test(expected=...)&lt;/code&gt;, donc. Fort heureusement, le champ logger dans X est une interface, potentiellement mockable :
&lt;pre class=&quot;brush: java;&quot;&gt;
interface Ilogger {
  public abstract void logError(final Key key, final Object... messages);
  // blabla
}&lt;/pre&gt;
Dans tous les cas où nous sommes intéressés, la méthode logError est appelée avec un paramètre Key représentant le code d&#039;erreur. Malheureusement, le logger n&#039;est pas injecté dans un setter, et il est privé. On aimerait tout de même vérifier que l&#039;erreur est bien logguée sous certaines conditions. Solution, un peu de réflexion pour forcer le champ logger à une instance que l&#039;on contrôle :
&lt;pre class=&quot;brush: java;&quot;&gt;
public class MockLogger implements ILogger {
  private List&amp;lt;Key&amp;gt; loggedKeys;

  public MockLogger() {
    super();
    loggedKeys = new ArrayList&amp;lt;Key&amp;gt;();
  }

  public void logError(Key key, Object... messages) {
    loggedKeys.add(key);
  }

  public boolean wasLogged(Key key) {
    return loggedKeys.contains(key);
  }

  public void resetLogCalls() {
    loggedKeys.clear();
  }
}&lt;/pre&gt;
La méthode &lt;code&gt;resetLogCalls&lt;/code&gt; permet d&#039;utiliser la même instance du logger sur plusieurs tests, il faut l&#039;appeler dans une méthode annotée &lt;code&gt;@After&lt;/code&gt;.

Il faut maintenant injecter notre propre logger dans le service testé :
&lt;pre class=&quot;brush: java;&quot;&gt;
Field f = serviceUnderTest.getClass().getDeclaredField(&quot;logger&quot;);
f.setAccessible(true);
f.set(serviceUnderTest, myLoggerInstance);
f.setAccessible(false);
&lt;/pre&gt;
Et voila, nous pouvons maintenant faire des &lt;code&gt;assertTrue&lt;/code&gt; utilisant la méthode &lt;code&gt;wasLogged&lt;/code&gt; et la Key nous intéressant ! Notez l&#039;appel à &lt;code&gt;Field#setAccessible(boolean)&lt;/code&gt; pour contourner le caractère private du champ &lt;code&gt;logger&lt;/code&gt; (que l&#039;on restaure par la suite).

Note : si le logger n&#039;avait pas utilisé d&#039;interface, nous aurions pu nous en sortir en créant une classe fille redéfinissant toutes les méthodes sans appels à &lt;code&gt;super()&lt;/code&gt;.</content>
</entry>
<entry>
	<title>Contrôler la bande passante de sa machine linux</title> 
	<link href="http://foobaz.free.fr/blog/?article5/controler-la-bande-passante-de-sa-machine-linux"/>
	<id>urn:md5:d3c162e487bc8a2a4d0dcf01ee89119f</id>
	<updated>2009-11-03T14:21:00+01:00</updated>
	<author><name>bastien</name></author>
	<dc:subject>Scripts</dc:subject>
	<content type="html">&lt;p&gt;Le haut débit c&#039;est bien, mais des fois on a quand même un côté nostalgique du 56k, soit parce qu&#039;on a envie d&#039;embêter les visiteurs de son serveur, soit parce que pour débugger une application (par exemple) on a envie que les données arrivent lentement. Sous linux, il existe la commande &lt;code&gt;tc&lt;/code&gt;, pour &lt;i&gt;traffic control&lt;/i&gt;, qui permet de contrôler ses connexions réseaux, notamment leur débit...&lt;/p&gt;&lt;p&gt;J&#039;ai donc trouvé un &lt;a href=&quot;http://www.topwebhosts.org/tools/traffic-control.php&quot;&gt;script tout fait&lt;/a&gt; permettant de limiter la bande passante d&#039;une interface réseau, en upload ou en download.
&lt;/p&gt;

&lt;pre class=&quot;brush: shell&quot;&gt;
#!/bin/bash
#
#  tc uses the following units when passed as a parameter.
#  kbps: Kilobytes per second 
#  mbps: Megabytes per second
#  kbit: Kilobits per second
#  mbit: Megabits per second
#  bps: Bytes per second 
#       Amounts of data can be specified in:
#       kb or k: Kilobytes
#       mb or m: Megabytes
#       mbit: Megabits
#       kbit: Kilobits
#  To get the byte figure from bits, divide the number by 8 bit
#

#
# Name of the traffic control command.
TC=/sbin/tc

# The network interface we&#039;re planning on limiting bandwidth.
IF=eth0             # Interface

# Download limit (in mega bits)
DNLD=1mbit          # DOWNLOAD Limit

# Upload limit (in mega bits)
UPLD=1mbit          # UPLOAD Limit

# IP address of the machine we are controlling
IP=216.3.128.12     # Host IP

# Filter options for limiting the intended interface.
U32=&quot;$TC filter add dev $IF protocol ip parent 1:0 prio 1 u32&quot;

start() {

# We&#039;ll use Hierarchical Token Bucket (HTB) to shape bandwidth.
# For detailed configuration options, please consult Linux man
# page.

    $TC qdisc add dev $IF root handle 1: htb default 30
    $TC class add dev $IF parent 1: classid 1:1 htb rate $DNLD
    $TC class add dev $IF parent 1: classid 1:2 htb rate $UPLD
    $U32 match ip dst $IP/32 flowid 1:1
    $U32 match ip src $IP/32 flowid 1:2

# The first line creates the root qdisc, and the next two lines
# create two child qdisc that are to be used to shape download 
# and upload bandwidth.
#
# The 4th and 5th line creates the filter to match the interface.
# The &#039;dst&#039; IP address is used to limit download speed, and the 
# &#039;src&#039; IP address is used to limit upload speed.

}

stop() {

# Stop the bandwidth shaping.
    $TC qdisc del dev $IF root

}

restart() {

# Self-explanatory.
    stop
    sleep 1
    start

}

show() {

# Display status of traffic control status.
    $TC -s qdisc ls dev $IF

}

case &quot;$1&quot; in

  start)

    echo -n &quot;Starting bandwidth shaping: &quot;
    start
    echo &quot;done&quot;
    ;;

  stop)

    echo -n &quot;Stopping bandwidth shaping: &quot;
    stop
    echo &quot;done&quot;
    ;;

  restart)

    echo -n &quot;Restarting bandwidth shaping: &quot;
    restart
    echo &quot;done&quot;
    ;;

  show)

    echo &quot;Bandwidth shaping status for $IF:&quot;
    show
    echo &quot;&quot;
    ;;

  *)

    pwd=$(pwd)
    echo &quot;Usage: tc.bash {start|stop|restart|show}&quot;
    ;;

esac

exit 0
&lt;/pre&gt;</content>
</entry>
<entry>
	<title>Pourquoi Netbeans c&#039;est bien</title> 
	<link href="http://foobaz.free.fr/blog/?article4/pourquoi-netbeans-c-est-bien"/>
	<id>urn:md5:489eceaeb1b57be1229ae462f2caf45d</id>
	<updated>2009-03-25T15:16:00+01:00</updated>
	<author><name>bastien</name></author>
	<dc:subject>Netbeans</dc:subject>
	<content type="html">&lt;p&gt;C&#039;est un fait avéré, Netbeans c&#039;est mieux qu&#039;Eclipse. &lt;small&gt;(comment ça, un troll tout poilu ?)&lt;/small&gt;. Pas plus tard qu&#039;il y a une minute, j&#039;en ai refait l&#039;heureuse expérience. Agacé de voir une série de getters/setters dans ma classe, qui sont triviaux à comprendre mais qui prennent de la place, j&#039;ai voulu utiliser l&#039;&lt;a href=&quot;http://wiki.netbeans.org/FaqCustomCodeFolds&quot;&gt;editor folding&lt;/a&gt;, propre à Netbeans (je crois, du moins). Ça consiste juste en deux commentaires autour du code que l&#039;on veut &lt;i&gt;folder&lt;/i&gt; (euh... comment traduit-on ça en français, déjà...) :

&lt;pre class=&quot;brush: java; highlight: [1,4]&quot;&gt;
    // &amp;lt;editor-fold defaultstate=&quot;collapsed&quot; desc=&quot;getters and setters&quot;&amp;gt;
    public Foo getFoo() { }
    public void setFoo(Foo foo) { }
    // &amp;lt;/editor-fold&amp;gt;
&lt;/pre&gt;

Maintenant vous aurez un joli &#039;-&#039; sur la gauche qui permettra de cacher tout ça et qui affichera la description voulue (ici, &quot;getters and setters&quot;).&lt;/p&gt;

&lt;p&gt;Amusons-nous encore un peu, en transformant ça en &lt;a href=&quot;http://wiki.netbeans.org/Java_EditorUsersGuide#section-Java_EditorUsersGuide-HowToUseLiveTemplates&quot;&gt;code template&lt;/a&gt; :&lt;/p&gt;
&lt;img src=&quot;data/images/code-templates.png&quot; alt=&quot;Code templates dans Netbeans&quot; /&gt;

&lt;p&gt;Et c&#039;est parti, sélectionnez un bloc de texte que vous ne voulez plus voir, puis cliquer sur l&#039;ampoule dans la gutter et choisissez &quot;Surround with an editor fold tag&quot;. Magique, non ?&lt;/p&gt;</content>
</entry>
<entry>
	<title>Récupérer de la musique depuis Deezer</title> 
	<link href="http://foobaz.free.fr/blog/?article3/recuperer-de-la-musique-depuis-deezer"/>
	<id>urn:md5:33698763b2d0f83d0a2a412e5b0500cf</id>
	<updated>2009-03-19T14:15:00+01:00</updated>
	<author><name>bastien</name></author>
	<dc:subject>Scripts</dc:subject>
	<content type="html">&lt;p&gt;Même si je ne suis pas trop fan de &lt;a href=&quot;http://www.deezer.com&quot;&gt;Deezer&lt;/a&gt; pour diverses raisons (interface Flash trop lourde, beaucoup trop de pub, ...), je suis quand même bien content de pouvoir y rechercher une musique que j&#039;ai en tête et que je peux récupérer pour la réécouter par la suite...&lt;/p&gt;&lt;p&gt;En effet, il est de notoriété publique que ce système met en cache la chason en cours d&#039;écoute et la stocke dans un fichier flv nommé /tmp/Flash* sous linux.&lt;/p&gt;
&lt;p&gt;À partir de là, il est facile de créer un script shell qui va se charger de récupérer ce ficher, puis d&#039;en extraire la musique en MP3 et de la sauvegarder dans notre dossier de musique favori. Top du top, le script que je vous propose par la suite permet également d&#039;éditer les tags ID3 et de renommer le fichier en conséquence, puis ajoute le morceau à la playlist Amarok en cours :D&lt;/p&gt;
&lt;p&gt;Voici la bête :&lt;/p&gt;
&lt;pre class=&quot;brush: shell&quot;&gt;
#!/bin/bash

DEST=/home/user/Musique

cd $DEST

files=`ls /tmp/Flash* | cut -d &#039;/&#039; -f3`

for file in $files
do
        ffmpeg -i &quot;/tmp/$file&quot; -acodec copy -f mp3 &quot;$DEST/$file.mp3&quot;
        id3ren -quick -notrack -template &quot;%a - %s.mp3&quot; &quot;$DEST/$file.mp3&quot;
        dcop amarok playlist addMedia &quot;$DEST/$file&quot;
done
&lt;/pre&gt;</content>
</entry>
<entry>
	<title>Security holes in symfony apps</title> 
	<link href="http://foobaz.free.fr/blog/?article2/security-holes-in-symfony-apps"/>
	<id>urn:md5:526838068f262f5b4a5c68e350589fbe</id>
	<updated>2008-12-01T21:52:00+01:00</updated>
	<author><name>bastien</name></author>
	<dc:subject>Symfony</dc:subject>
	<content type="html">&lt;p&gt;symfony 1.2 was just released, and came along with a brand new advent calendar. &lt;a href=&quot;http://www.symfony-project.org/jobeet/1_2/en/01&quot;&gt;The first day&lt;/a&gt; mentions two ways to set up your web server to host a symfony project. &lt;a href=&quot;http://www.symfony-project.org/jobeet/1_2/en/01#Web Server Setup: The ugly Way&quot;&gt;The ugly way&lt;/a&gt; seems to be very... ugly and crazy, putting your app directly in your webserver&#039;s root folder allows anyone to access all the files. But this security hole can be easily found in &#039;real&#039; apps, as well as a few others...&lt;/p&gt;
&lt;p&gt;
This article will try to enumerate some of the mistakes that are often done when a symfony application is put in production environment.
&lt;/p&gt;

&lt;h2&gt;Development environment is still present&lt;/h2&gt;
&lt;p&gt;These files, ending with _dev.php, are very useful when you are coding: they provide a lot of information on the configuration, the SQL queries that were executed, your PHP version etc. But on the other hand, they should never be accessible to your visitors (I mean, bad ones, you know, those who type in the darkness). They can show your kernel version, the symfony plugins which are installed, the escaping method you are using (or &lt;i&gt;not&lt;/i&gt; using...), etc., which can lead to other vulnerabilities.&lt;p&gt;

&lt;h2&gt;The project root is the webserver&#039;s root folder&lt;/h2&gt;
&lt;p&gt;This can also give a lot of information to an attacker, especially your database connection settings. Just search for &#039;web/frontend.php&#039; in your favorite search engine, and you will have a bunch of apps which are potentially in this case. Then you just have to browse config/databases.yml and you get what you want. Just consider that if the application is unsecure, the webserver which is running it is also unsecure, and you can have a remote access to MySQL on port 3306, which will show you a lot of interesting things...&lt;/p&gt;

&lt;h2&gt;The backend is not protected&lt;/h2&gt;
&lt;p&gt;
Harder to find, but not impossible. Even if this page is not indexed by search engines, it&#039;s quite easy to see if a web app is powered by symfony, and the majority of these web apps have a backend which is called &#039;backend&#039; (if not, just try &#039;admin&#039; :)). So it&#039;s very important to restrict access to this backend, as it can contain sensitive information (user accounts, etc.). Imagine that you didn&#039;t make a recent backup of your database, and that someone deletes all its content...
&lt;/p&gt;

&lt;h2&gt;How to fix it?&lt;/h2&gt;
&lt;p&gt;
It&#039;s not difficult to avoid these problems. In fact, the solutions are very well explained in the official symfony book, but nonetheless they are often not applied.&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;Check that *_dev.php files are not uploaded (see the rsync_excludes.txt file for example)&lt;/li&gt;
 &lt;li&gt;If you can, put the whole project (except the web/ folder) outside the web document root&lt;/li&gt;
 &lt;li&gt;Protect your backend with sfGuard, or at least a htaccess/htpasswd file :) (and do not user admin/admin or something like this)&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;</content>
</entry>
</feed>