<?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>The moons of Verthandi - Blog by Dani Giribet</title>
	<atom:link href="http://dani.calidos.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://dani.calidos.com</link>
	<description></description>
	<lastBuildDate>Mon, 02 Apr 2012 16:42:36 +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>El conflicte entre les xarxes socials i els mitjans de comunicació</title>
		<link>http://dani.calidos.com/2012/02/12/el-conflicte-entre-les-xarxes-socials-i-els-mitjans-de-comunicacio/</link>
		<comments>http://dani.calidos.com/2012/02/12/el-conflicte-entre-les-xarxes-socials-i-els-mitjans-de-comunicacio/#comments</comments>
		<pubDate>Sun, 12 Feb 2012 19:16:19 +0000</pubDate>
		<dc:creator>dani</dc:creator>
				<category><![CDATA[Catalan]]></category>
		<category><![CDATA[Entertainment]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[Media]]></category>
		<category><![CDATA[Random]]></category>
		<category><![CDATA[economia]]></category>
		<category><![CDATA[evolució]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[memes]]></category>
		<category><![CDATA[mtv]]></category>
		<category><![CDATA[replicators]]></category>
		<category><![CDATA[superfreakonomics]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[xarxes socials]]></category>
		<category><![CDATA[xing]]></category>
		<category><![CDATA[youtube]]></category>

		<guid isPermaLink="false">http://dani.calidos.com/?p=387</guid>
		<description><![CDATA[En aquest article parlaré de la confrontació silenciosa actual entre els mitjans de comunicació i les les xarxes socials. Els mitjans no estan desapareixent, ni tampoc saltant pels aires, sino sofrint una erosió terrible en un conflicte que està canviant &#8230; <a href="http://dani.calidos.com/2012/02/12/el-conflicte-entre-les-xarxes-socials-i-els-mitjans-de-comunicacio/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>En aquest article parlaré de la confrontació silenciosa actual entre els mitjans de comunicació i les les xarxes socials. Els mitjans no estan desapareixent, ni tampoc saltant pels aires, sino sofrint una erosió terrible en un conflicte que està canviant la indústria de la comunicació mica en mica, tuit a tuit, post a post.</p>
<p><a href="http://dani.calidos.com/wp-content/uploads/2012/02/els-fronts-de-batalla.png"><img src="http://dani.calidos.com/wp-content/uploads/2012/02/els-fronts-de-batalla.png" alt="Els mitjans tradicionals arrossegats a la batalla amb les grans xarxes socials" title="Els fronts del conflicte" width="670" height="395" class="aligncenter size-full wp-image-397" /></a><br />
<span id="more-387"></span><br />
Durant la primera guerra mundial i un cop superada la primera fase de la gran ofensiva alemanya, els estrategues del Kaiser i més concretament, el tinent-coronel Richard Hentsch va veure evident que el gran pla de derrotar França per la via ràpida, el pla Schlieffen, havia fracassat.</p>
<p>A principis de setembre del 1914, els soldats alemanys participants en l&#8217;ofensiva nord, sota les ordres de Hentsch, van situar-se en posicions favorables i es van posar a cavar trinxeres. Unes fortificacions que definiren els anys següents de la guerra i que no es mourien, -almenys les del front nord de París- fins el 1917.</p>
<p>En el bàndol alemany, Hentsch seria rellevat pel general Erich von Falkenhayn, pero les defences ja estaven apunt. Així va començar una guerra sagnant de trinxeres, on quedava clar cap a on s&#8217;havia de disparar i qui era l&#8217;enemic, fos quin fos el bàndol.</p>
<p>Els temps canvien i els conflictes també. La segona guerra mundial, amb la Blitzkrieg, la modernització dels carros blindats i l&#8217;aviació deixarien l&#8217;atrinxerament estàtic en el passat.</p>
<h2>La competència en els mitjans de comunicació en el passat</h2>
<p>En temps més moderns, el conflicte entre els mitjans de comunicació ha estat de &#8216;trinxeres&#8217;. Primerament, la competència es limitava a les <a title="BBC site" href="http://www.bbc.co.uk/ ">empreses</a> d&#8217;un mateix país, regió, <a title="La Commonwealth" href="http://en.wikipedia.org/wiki/Commonwealth_of_Nations">àrea d&#8217;influència lingüística o cultural</a>.</p>
<p>Els continguts internacionals, com la CNN o la MTV tenien un impacte limitat tot i emetre&#8217;s bàsicament en obert. Entre altres raons com poden ser la òbvia barrera idiomàtica trobem la dificultat tecnològica d&#8217;instal·lar i operar un receptor de satèl·lit.</p>
<p>Eren dies més feliços, els mitjans nacionals o regionals coneixien molt bé als seus rivals de l&#8217;altre costat de la trinxera. En el cas de la televisió i la ràdio, per exemple, l&#8217;accés a una llicència d&#8217;emissió el regula l&#8217;administració, creant unes barreres d&#8217;accés immenses. A més, el cost de les infraestructures d&#8217;emissió, sobretot en el cas de la TV, eren i són molt grans, o si no que li ho preguntin a la xarxa de televisions locals. Les despeses de distribució de la premsa escrita tampoc són</p>
<p>Aquests temps es marcaven per uns canvis de quota de mercat relativament petits i uns canvis en els hàbits de consum gairebé inexistents. No costa gaire d&#8217;imaginar en el temps de la &#8216;primera cadena&#8217; en l&#8217;estat Espanyol com en moltes llars no es canviava mai de canal.</p>
<p>D&#8217;aquestes barreres d&#8217;entrada, la relativa escassetat d&#8217;alternatives i en alguns casos també la qualitat dels continguts va fonamentar el model de negoci basat en la publicitat encara en ús avui en dia (sí, sí, sumat a altres d&#8217;auxiliars).<br />
Sense cap mena de dubte, l&#8217;exemple més clar és quan costa el fet que surti el logo de la teva empresa per pantalla durant 20 segons.</p>
<p>Segons <a title="Preus dels espots" href="http://www.oblicua.es/publicidad/publicidad-tv-television.htm">Oblicua</a>, un espot en prime time a Telecinco pot arribar a costar 20.000€. Això sense comptar agències i intermediaris, la realització de l&#8217;espot en sí, etc.</p>
<p>Desde els temps del naixement de la premsa escrita els grans grups i empreses de comunicació es van fonamentar, crèixer i consolidar en aquesta situació. Molts cops aprofitant la tecnologia anterior com a plataforma de llançament, com en el cas de la BBC passant de fer ràdio a fer també tele.</p>
<p>L&#8217;arribada de les noves tecnologies i sobretot la Web va suposar evidentment una gran revolució a moltíssims nivells. Al principi, però els canvis tecnològics feien endevinar grans coses a uns pocs gurús però tampoc semblava que arribessin a tenir tant impacte.</p>
<p>Tal com va passar amb els primers carros blindats, inventats i desplegats a la Gran Guerra. Eren lents, relativament poc efectius i amb molta tendència a deixar els soldats &#8216;tirats&#8217;. Pocs anys més tard els tancs serien claus pels Nazis, ajudant a conquerir mitja Europa amb atacs llampec.</p>
<h2>L&#8217;atac del contingut generat per l&#8217;usuari</h2>
<p>Tornant al passat recent. L&#8217;advent de la Web en sí i sobretot del UGC (Contingut Generat per l&#8217;Usuari) amb la popularització de <a title="Informació general sobre l'empresa" href="http://en.wikipedia.org/wiki/YouTube">YouTube</a> (creat al 2005) van fer presagiar a uns quants d&#8217;aquests gurus la &#8220;desaparició&#8221; o si més no la decadència dels mitjans tradicionals. Va ser una moda divertida i de fet, encara hi ha gurús que ho prediquen.</p>
<p>Qualsevol persona que hagi provat de fer un curt de cinema o tele sabrà que fer continguts de qualitat no és gens fàcil, ni normalment tampoc barat. Per molt accessible que sigui la tecnologia de blogs, WordPress, etc. escriure un bon article o tutorial comporta feina i fer una recerca com toca. Tampoc ens emocionem i ens ajuntem amb els &#8216;gurús&#8217;. Com a mínim es necessita una bona història i no surten de totes les pedres, per moltes <a title="Empresa de càmeres d'altes prestacions" href="http://www.red.com/">Red One</a> que es comprin.</p>
<p>En el moment de començar a escriure aquest post, fent una mirada als vídeos més vistos a tot el món a YouTube ens dóna</p>
<p><a href="http://dani.calidos.com/wp-content/uploads/2012/02/ugc-youtube.png"><img class="aligncenter size-full wp-image-388" title="Contingut més vist a youtube" src="http://dani.calidos.com/wp-content/uploads/2012/02/ugc-youtube.png" alt="Els vídeos més vistos" width="983" height="497" /></a></p>
<p>1.- &#8216;<a href="http://www.youtube.com/watch?v=i47HoiM0Au8">My Tram Experience</a>&#8216;<br />
En aquest cas UGC i del bo.</p>
<p>2.- <a href="http://www.youtube.com/watch?v=6I3kgbBp6PY">We Found Love &#8211; Rihanna feat. Calvin Harris (Boyce Avenue piano acoustic cover) on iTunes</a><br />
Vídeo professional, links al iTunes inclosos. Per cert el Calvin Harris sona molt retocat i tampoc us perdeu la caixa flamenca. Pot semblar més o menys fluixet però la iluminació no està feta amb unes bombetes de baix consum.</p>
<p>3.- <a href="http://www.youtube.com/watch?v=PGc9n6BiWXA">Beyoncé &#8211; Dance For You</a></p>
<p>Professional.</p>
<p>4.- <a href="http://www.youtube.com/watch?v=I8t9N8AlMYk">Exclusive: Miley says &#8216;Weed my lips!&#8217;</a><br />
Vídeo capturat amb un mòbil però publicat pel &#8216;<a title="Revista digital per iPad" href="http://www.thedaily.com/about">The Daily</a>&#8216;, un diari per iPad digital. Low-cost, però un mitjà professional. A no ser que us agradi el &#8216;gossip&#8217; groguenc UK no cal que cliqueu a l&#8217;enllaç.</p>
<p>5.- <a title="Recepció espectacular" href="http://www.youtube.com/watch?v=YCdFFFAxLz0">Aaron Dobson &#8220;The Catch&#8221;</a></p>
<p>Professional. No us perdeu la recepció del <a href="http://www.herdzone.com/sports/m-footbl/mtt/dobson_aaron00.html">Dobson</a>, espectacular.</p>
<p>6.- <a href="http://www.youtube.com/watch?v=vcZbvLY0hFA">Fail Compilation November 2011 || TNL</a></p>
<p>UGC, amb alguna part extreta de contingut pro. Veient-ne alguns fragments hom es pregunta com pot ser que la raça humana hagi sobreviscut fins ara. Excepte el trosset amb uns castellers fent llenya, que al personatge creador de la compilació deu ser l&#8217;únic a qui li fa gràcia. Pels colors semblen els <a href="http://www.minyons.cat/">Minyons de Terrassa</a>.</p>
<p>No és un estudi científic però tampoc es podria dir que <strong>pel contingut en sí</strong> els mitjans i productores es vegin molt amenaçats directament pel que fa a la qualitat. A més, últimament es veuen molts anuncis al YouTube, amb part dels ingressos que van a parar als creadors del contingut. No és preocupant, de moment, però val la pena tenir-hi un ull posat per veure com evoluciona.</p>
<p>Avui en dia, i tal com reflexa aquesta prova informal, es podria dir que la &#8216;moda&#8217; del UGC ha minvat i s&#8217;ha acabat assemblat una mica al contingut més &#8216;mainstream&#8217;.</p>
<h2>La següent era: la vinguda de les xarxes socials</h2>
<p>Les coses han canviat i la natura de la xarxa evoluciona molt ràpidament, el conflicte, muta. Com si res, passem d&#8217;una gran guerra a una altra.<br />
Amb l&#8217;explosió de l&#8217;ús de les xarxes socials, com pot ser Facebook, amb un <a title="Creixement del FB per països" href="http://www.nickburcher.com/2012/01/facebook-usage-statistics-by-country.html">creixement espectacular</a> en els últims anys.</p>
<p><a href="http://dani.calidos.com/wp-content/uploads/2012/02/creixement-absolut.png"><img class="aligncenter size-full wp-image-390" title="Creixement d'usuaris de Facebook" src="http://dani.calidos.com/wp-content/uploads/2012/02/creixement-absolut.png" alt="Gràfica 'Creixement d'usuaris de Facebook'" width="600" height="371" /></a></p>
<p><a href="http://dani.calidos.com/wp-content/uploads/2012/02/percentatge-sobre-poblacio-total.png"><img class="aligncenter size-full wp-image-391" title="Percentatge d'usuaris de Facebook sobre la població total" src="http://dani.calidos.com/wp-content/uploads/2012/02/percentatge-sobre-poblacio-total.png" alt="Gràfica 'Percentatge d'usuaris de Facebook sobre la població total'" width="600" height="371" /></a></p>
<p>I quin impacte té, l&#8217;ofensiva de les xarxes socials en els mitjans de comunicació?</p>
<h2>El primer impacte: les URLs</h2>
<p>Es pot començar per molts llocs, però començem per una de les eines d&#8217;accés als continguts online més importants: les adreçes URL.</p>
<p>Bé, agafem per exemple l&#8217;excel·lent programa de RAC1 &#8216;La Competència&#8217; i les següents URLs:</p>
<p><a title="La Competència" href="http://www.facebook.com/lacompetencia">http://www.facebook.com/lacompetencia</a><br />
<a title="La Competència" href="http://twitter.com/lacompetencia">http://twitter.com/lacompetencia<br />
</a></p>
<p>O en les del conegut programa de debats esportius Punto Pelota de Josep Pedrerol:</p>
<p><a title="Punto Pelota" href="https://www.facebook.com/puntopelota">https://www.facebook.com/puntopelota<br />
</a><a title="Punto Pelota" href="https://twitter.com/puntopelota">https://twitter.com/puntopelota<br />
</a></p>
<p>En aquestes URLs i en les de molts productes audiovisuals i de comunicació no surt enlloc la marca mare, el diari, cadena de ràdio o televisió que creen aquest contingut.</p>
<p>Resultat: la marca mare es dilueix cada vegada que es publiquen, esmenten, visualitzen o comuniquen aquestes adreçes. I a més, la marca contenidora de la xarxa social en qüestió va sempre primer.</p>
<p>En el cas del Twitter, si s&#8217;utilitzen hash tags per promocionar continguts com es fa per exemple en algunes sèries americanes posant el tag com una mosca discreta llavors es l&#8217;impacte és menor (com passa per exemple amb la promo de Twitter que es fa a la sèrie <a title="Hashtag de Fringe" href="https://twitter.com/#!/search/%23fringe">Fringe</a>).</p>
<p>Tot i que l&#8217;accés a la Web avui en dia es fa en un percentatge significatiu amb el cercador Google, no podem descartar l&#8217;impacte debilitant en les marques &#8216;mare&#8217; pel fet que brillin per la seva absència en les URLs publicitades.</p>
<h2>En defensa de les xarxes: el tràfic d&#8217;entrada</h2>
<p>Dins del tema de l&#8217;accés i els sitemes d&#8217;entrada als continguts interactius dels mitjans, si es miren les dades de seguida podem comprovar que un percentatge molt gran ens ve de les pròpies xarxes socials, apart del que pugui venir directament o del cercador de Google.</p>
<p>Clar, amb la immensa promoció que s&#8217;en fa&#8230;</p>
<p>Escoltem el programa d&#8217;avui de <a title="La Competència" href="http://rac1.org/lacompetencia/">La Competència</a>:</p>
<p><strong>Mencions de RAC1</strong>: 12 (inclou les auto promos i la careta del programa)<br />
<strong>Mencions de &#8216;La Competència&#8217;</strong>: 14<br />
<strong>Mencions de FaceBook</strong>: 2<br />
<strong>Mencions de Twitter</strong>: 2</p>
<p>Proporcionalment, no són moltes mencions, però es produeixen a cada programa, tot l&#8217;any. Els anunciants també surten, però no a cada programa i ni molt menys tota la temporada, si no és pagant, és clar.<br />
Quantes setmanes té la temporada? 42? Això són 42x5x4=840.</p>
<p><em>&#8220;Hola, RAC1?!? Voldria que l&#8217;Òscar Dalmau digués el nom de la meva marca mil cops per temporada. Quan val?&#8221;</em></p>
<h2>El &#8216;preu&#8217; de la publicitat</h2>
<p>Fem uns càlculs ràpids.</p>
<p>Segons <a title="Radioes.net" href="http://www.radioes.net">Radioes.net</a>, a la província de Barcelona hi ha 124 emissores, a Lleida 51, a Girona 54 i a Tarragona 43. Si considerem un solapament de les ràdios a nivell català d&#8217;un 40% ens queden unes 160 amb números rodons. Per tant, si cada emissora té 10 programes que fan 1000 esments per temporada i tenim 160x10x1000 = 1.6 milions d&#8217;esments per temporada a la ràdio catalana. Multipliquem per 50 a Espanya i fent números rodons ens quedem diguem amb 70 milions d&#8217;esments per temporada.</p>
<p>Estem parlant de mini promocions fetes per locutors amb molta credibilitat i de personatges famosos, de forma contínua, uniforme i en totes les emissores</p>
<p>Si afegim els mitjans televisius quants centenars de milers o milions de &#8216;promos&#8217; més per temporada llavors tenim?</p>
<p>Si recordem, un espot de tele pot arribar a costar 20.000€ en prime-time, quan la gent desconnecta o va al lavabo. Però integrats en el propi programa tal com passen aquestes mini promos és força més efectiu i impactant. Si es quantifica el cost en euros d&#8217;aquesta publicitat quan valdria? Milions d&#8217;euros? Una campanya per tot el país, en tots els mitjans de comunicació, en boca de conductors, presentadors, locutors i personatges famosos, en mitjans grans i petits.</p>
<p>I tot això a cost zero per Facebook i Twitter.</p>
<p>Clar que ve tràfic de les xarxes socials, només faltaria, amb la publicitat que se&#8217;ls està regalant. És una promesa feta realitat, les accions d&#8217;un profeta que fan que es compleixin els seus auguris.</p>
<h2>La segona línia de defensa: l&#8217;efectivitat tècnica de les xarxes socials</h2>
<p>Només cal ser usuari actiu de Facebook o Twitter per comprovar que són productes interactius excel·lents. Són funcionalment molt bons, amb un disseny espartà però funcional i distintiu, una estabilitat a prova de bomba i un temps de resposta rapidíssim. A més, constantment van evolucionant i afegint millores, sobretot en el cas de Facebook, que té una política més expansiva.</p>
<p>Els equips de producte i desenvolupament tècnic d&#8217;aquestes empreses són modèlics, amb plantilles motivades, joves, dinàmiques, molt ben preparades i a sobre ben pagades. La seva orientació a producte és total i absoluta, per alguna cosa Mark Zuckerberg va ser tutelat per Steve Jobs (un dels millors si no el millor cap de producte de la història).</p>
<p>Comparat amb aquesta efectivitat, els productes d&#8217;interacció fets a casa dels mitjans de comunicació acostumen a ser molt dignes però molt sovint no arriben a assolir el mateix nivell d&#8217;excel·lència. Ja siguin fets a mida, comprats o adaptats de codi lliure, els equips de producte i desenvolupament que els despleguen estan molts cops infradimensionats i amb una orientació diferent. A vegades també comparteixen responsabilitats amb els aspectes tècnics i de concepte de l&#8217;activitat pròpia d&#8217;un mitjà de comunicació. El dimensionament i l&#8217;encaix de la interactivitat en un mitjà tradicional encara no està del tot resolt. L&#8217;outsourcing o la compra de productes claus en mà tampoc sembla ser la solució perquè no deixa de ser una porta fàcil de sortida que rebaixa la capacitat de diferenciació de producte, homologant el servei d&#8217;un mitjà a la resta.</p>
<p>Amb aquesta situació els mitjans competeixen amb els equips estrella de les xarxes socials amb totes les de perdre. Els productes de Facebook i Twitter funcionen millor, són més estables i a sobre, són &#8220;gratis&#8221;. Cada cop més, els mitjans aposten més fort per deixar de banda els productes d&#8217;interacció propis i centrar-se en els productes enllaunats que ens ofereixen les xarxes socials.</p>
<p>Per veure el que ens ha portat fins aquí hem d&#8217;entrar en l&#8217;àmbit de l&#8217;economia a gran escala. A <a title="Superfreakonomics a Amazon" href="http://www.amazon.co.uk/Superfreakonomics-Cooling-Patriotic-Prostitutes-Insurance/dp/0141030704/ref=sr_1_1?ie=UTF8&amp;qid=1327878734&amp;sr=8-1">Superfreakonomics</a>, de l&#8217;economista <a title="Steven Levitt" href="http://en.wikipedia.org/wiki/Steven_Levitt">Steven D. Levitt</a> i el periodista <a title="Stephen Dubner" href="http://stephenjdubner.com/">Stephen J. Dubner</a>, es donen detalls de l&#8217;impacte dels incentius en els processos globals. Concretament parlen del concepte en economia de l&#8217;externalitat. L&#8217;externalitat és el que passa quan una persona emprèn una acció però totes o part de les conseqüències les paga algú altre i sense tenir cap acord.</p>
<p>Un bon exemple d&#8217;externalitat són els gasos que desprenem en la nostra activitat diària que es sumen a l&#8217;efecte hivernacle i possiblement a l&#8217;escalfament global. La tecnologia actual és tant potent que emmascara les conseqüències de les nostres accions, com passa quan posem l&#8217;aire acondicionat a tope i no veiem pas el fum de la central tèrmica que ens dóna l&#8217;energia necessària, com tampoc les deixalleries situades en països del tercer món.</p>
<p>En aquesta línia, desenvolupar o integrar productes interactius de qualitat requereix molt temps i esforç, essent els guanys més substancials molt a llarg termini. Aquests incentius contrastats amb la facilitat d&#8217;implantació dels productes de sindicació de Facebook i Twitter fan que els mitjans es vagin decantant per la via de les xarxes socials. L&#8217;impacte que cada acció és una externalitat que té unes conseqüencies per la indústria reals però llunyanes i impercebtibles. I sentim frases com: &#8220;ja se n&#8217;encarregarà algú altre, de competir amb ells&#8221;, &#8220;això és cosa de la privada&#8221;, &#8220;de la pública&#8221;, &#8220;nosaltres som massa petits, això els grans mitjans&#8221;, etc.</p>
<p>Cada petita acció, cada tuit i cada post, són externalitats que alimenten els gegants.</p>
<h2>La tercera defensa: &#8220;som un mitjà&#8221;</h2>
<p>Potser la frase més repetida per alguns escèptics seria: &#8220;nosaltres som un mitjà de comunicació, no pas una empresa tecnològica, per tant ens quedem amb Facebook&#8221;. Una afirmació ben certa i potser definint una estratègia &#8216;guanyadora&#8217;. Guanyadora si no fos pel fet que Facebook i Twitter també són mitjans de comunicació. Mitjans que en plantilla només tenen equips de producte i desenvolupament i que externalitzen tots els seus continguts (i gratis).</p>
<p>Twitter i Facebook, mitjans de comunicació?</p>
<p>Examinem, per exemple el model de negoci de Facebook. Facebook ven publicitat als seus clients que són els anunciants per obtenir impressions publicitàries generades pels seus usuaris. Degut a les dades extenses sobre els mateixos i la seva activitat, pot oferir anuncis als seus clients dirigits a públics molt concrets. A més, els continguts són tots externs, regalats a cost zero pels propis usuaris i els diferents mitjans de comunicació.</p>
<p>Un mitjà de comunicació televisiu ven publicitat als seus clients que són els anunciants per obtenir impressions publicitàries vistes per la seva audiència. Degut als diferents canals, programes i franges horàries, pot oferir anuncis als seus clients dirigits a públic més o menys concrets. Ah, els continguts són tant interns com externs i costen molts diners.</p>
<p>No hi ha gaires diferències. Sí, que els continguts no hi són en la seva totalitat a Facebook, però en són com a mínim els aparadors i sovint els contenidors. L&#8217;altra diferència és que a Facebook només hi ha equips de desenvolupament (i comercials!).</p>
<h2>L&#8217;última línia de defensa: l&#8217;autopreservació de la xarxa social</h2>
<p>Apart dels formidables arguments presentats, resta el potent efecte &#8216;xarxa&#8217; i d&#8217;autopreservació de les xarxes socials amb suficient massa crítica. Richard Dawkins en parla d&#8217;efectes similars a &#8216;<a title="Llibre The Extended Phenotype a Amazon" href="http://www.amazon.co.uk/Extended-Phenotype-Reach-Popular-Science/dp/0192880519/ref=sr_1_1?ie=UTF8&amp;qid=1329058905&amp;sr=8-1">The Extended Phenotype</a>&#8216;, &#8216;<a title="Llibre The Selfish Gene a Amazon" href="http://www.amazon.co.uk/Selfish-Gene-30th-Anniversary/dp/0199291152/ref=sr_1_1?ie=UTF8&amp;qid=1329059055&amp;sr=8-1">The Selfish Gene</a>&#8216; i a &#8216;<a title="The God Delusion a Amazon" href="http://www.amazon.co.uk/God-Delusion-Richard-Dawkins/dp/055277331X/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1329058942&amp;sr=1-1">The God Delusion</a>&#8216;, encunyant els termes &#8216;replicador&#8217; (replicator) i &#8216;meme&#8217;.</p>
<p>Segons Dawkins, un replicador és un &#8220;qualsevol cosa en l&#8217;univers de la que s&#8217;en fan còpies&#8221;, amb els gens i l&#8217;ADN com a exemples paradigmàtics. En canvi, un &#8216;meme&#8217; és un replicador cultural, una idea que s&#8217;autoreplica i viu en les persones. O tal com diu el mateix Cobb en la fantàstica película de Christopher Nolan, <a title="Tràiler d'Inception" href="http://www.youtube.com/watch?v=_zfMZaLoAsY">Inception</a></p>
<p><em>&#8220;What is the most resilient parasite? Bacteria? A virus? An intestinal worm?<br />
An idea. Resilient&#8230; highly contagious. Once an idea has taken hold of the brain it&#8217;s almost impossible to eradicate. An idea that is fully formed &#8211; fully understood &#8211; that sticks; right in there somewhere. &#8220;</em></p>
<p>L&#8217;essència d&#8217;una xarxa social és una idea brillant que es replica de cervell a cervell, de persona a persona, de follower a follower. Per exemple, Facebook només és útil si també ho utilitzen les coneixençes dels propis usuaris, que treballen activament perque sigui així. La pròpia idea d&#8217;una xarxa social en sí treballa perque el meme es repliqui de forma molt activa. Si no s&#8217;escampa la idea no val la pena ser usuari d&#8217;una xarxa social. Aquesta capacitat de replicació fa que un cop s&#8217;agafa suficient massa crítica l&#8217;estabilitat de la xarxa és molt gran, i d&#8217;alguna manera, es sustenta a sí mateixa.</p>
<p>Els memes dels mitjans tradicionals no requereixen ni tampoc busquen de forma tant agressiva la replicació activa i a més, la creixent aparició del contingut sota-demanda fa la replicació en tals mitjans no sigui tant necessària com abans. Abans de l&#8217;aparició de la Web i el vídeo IP amb la seva multitud de formes, els televidents veien els continguts prime-time al vespre i els comentaven l&#8217;endemà a la feina, a l&#8217;escola, etc. Una forma efectiva de replicació però que ja no s&#8217;estila tant, en pro de la Web i les xarxes socials.</p>
<h2>El nou conflicte global</h2>
<p>A diferència de molts mitjans, Google ha sabut reconèixer la naturalesa de l&#8217;adversari, ha establert els fronts, cavat les trinxeres i passat a <a title="Integració Google+ i Google" href="http://searchengineland.com/examples-google-search-plus-drive-facebook-twitter-crazy-107554 ">l&#8217;ofensiva</a> amb Google+.</p>
<p>El model de negoci del cercador de Google també es basa en la publicitat, <a href="http://venturebeat.com/2012/01/29/google-advertising/ " title="Google depén de la publicitat">en un 96% l&#8217;any 2011</a> i en aquesta línia, Google aconsegueix tants diners a canvi de presentar anuncis rellevants als seus usuaris en base al seu comportament i a les cerques. Certament es tracta d&#8217;un model molt similar al de Facebook i Twitter. Google ha sabut veure l&#8217;existència del conflicte i preveure que en vindran de més madures conforme es vagi enforting la relació directa entre anunciants, marques i els usuaris a traves de les xarxes socials.</p>
<p>D&#8217;aquí el llançament de Google+ i seva la potserior vinculació amb el producte estrella, el cercador. Sense cap dubte, Google ha sabut reconèixer els fronts principals que té oberts tot i que potser en són <a title="Google amb més fronts oberts" href="http://dani.calidos.com/2011/03/27/nokia-google-microsoft-without-any-options/ ">masses</a>, tal com li va passar als imperis alemany i austrohongarès.</p>
<p>Potser, tal com fa Google, els mitjans de comunicació tradicionals han de reconèixer l&#8217;existència del conflicte. Aquest seria el primer pas i que donaria pas a l&#8217;acció més important, la definició d&#8217;una estratègia unificada i coherent. Com qualsevol estratègia, hi han riscos i avantatges en qualsevol de les accions, alguns exemples:</p>
<ul>
<li>Aliança completa amb Facebook i Twitter: establir una política d&#8217;immersió completa, esperant que la resta de mitjans de la competència no ho facin tant bé i viure en comfort a l&#8217;ombra d&#8217;aquests gegants de la comunicació global. Els avantatges principals d&#8217;aquesta estratègia oportunista són el baix cost, el guany de tràfic a curt termini i la simplicitat. El desavantatge és la pèrdua de la relació directa amb els usuaris i la supeditació a l&#8217;estratègia de tercers.</li>
<li>Crear-se la xarxa social pròpia, només viable realment en mitjans amb moltíssima massa crítica i una capacitat de crear producte de primer nivell. Amb un cost i riscs elevats, es manté el coneixement a la casa i es fidelitza directament als usuaris.</li>
<li>Unificar la comunicació i vehicular-la a través de productes propis: en comptes de publicitar les URLs de la competència, comunicar estrictament només URLs del propi mitjà, on es poden trobar llavors els diferents accessos a les xarxes socials més les eines de participació pròpies i alienes. La comunicació de la participació s&#8217;unifica i simplifica mentres s&#8217;espera cap a on bufa el vent.</li>
</ul>
<p>Sigui quina sigui l&#8217;estratègia, no es pot deixar res a l&#8217;atzar i els controls interns sobre les marques, els canals de participació i fidelització han de ser més grans que mai, a risc d&#8217;acabar com els perdedors d&#8217;aquest gran conflicte. En la Gran Guerra, Europa es va redibuixar, imperis sencers que semblaven inamovibles van caure i les coses van canviar per sempre, almenys fins al següent conflicte.</p>
]]></content:encoded>
			<wfw:commentRss>http://dani.calidos.com/2012/02/12/el-conflicte-entre-les-xarxes-socials-i-els-mitjans-de-comunicacio/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Building an FTP server Maven plugin from scratch</title>
		<link>http://dani.calidos.com/2011/08/15/building-an-ftp-server-maven-plugin-from-scratch/</link>
		<comments>http://dani.calidos.com/2011/08/15/building-an-ftp-server-maven-plugin-from-scratch/#comments</comments>
		<pubDate>Mon, 15 Aug 2011 20:23:47 +0000</pubDate>
		<dc:creator>dani</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[apache commons net]]></category>
		<category><![CDATA[apache ftp server]]></category>
		<category><![CDATA[apache mina]]></category>
		<category><![CDATA[ftp]]></category>
		<category><![CDATA[ftp server]]></category>
		<category><![CDATA[integration testing]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[maven failsafe plugin]]></category>
		<category><![CDATA[maven surefire plugin]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://dani.calidos.com/?p=362</guid>
		<description><![CDATA[In this post we design and code a new Maven plugin that fires up a FTP server to aid in integration testing of FTP-bound processes, thus demonstrating the flexibility and power of Maven plugins. Introducing Maven and testing It is &#8230; <a href="http://dani.calidos.com/2011/08/15/building-an-ftp-server-maven-plugin-from-scratch/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In this post we design and code a <strong>new Maven plugin</strong> that fires up a FTP server to aid in integration testing of FTP-bound processes, thus demonstrating the flexibility and power of Maven plugins.</p>
<h3>Introducing Maven and testing</h3>
<p>It is well known and accepted that the <a href="http://maven.apache.org/" title="Apache Maven">Maven</a> build system from Apache is very powerful and capable. It is also easy to use and hard to master.</p>
<p><a href="http://maven.apache.org/plugins/index.html " title="Official Maven plugin list">Countless</a> plugins to extend its functionality <a href="http://code.google.com/hosting/search?q=maven+plugin+label%3Amaven&#038;projectsearch=Search+Projects" title="Maven plugin search">can be found</a>.</p>
<p>One of the main functionalities offered by Maven is assisting in various levels of testing, made possible by some powerful plugins.</p>
<p>In building and testing software, individual software components and classes should be <a href="http://en.wikipedia.org/wiki/Unit_testing" title="Unit Testing">unit tested</a> using mockup objects and at a level of granularity that is independent of any services being available, both internal and external.</p>
<p>In this case Maven offers very good solutions, such as the ubiquitous <a href=" http://maven.apache.org/plugins/maven-surefire-plugin/ " title="Maven official unit testing plugin">Surefire plugin</a>. Using this plugin unit testing with a variety of testing frameworks is quite straightforward and easy.</p>
<p>On the other hand, <a href="http://en.wikipedia.org/wiki/Software_testing#Integration_testing" title="Integration Testing">Integration Testing</a> is done at a higher level, verifying that the integration between components, both internal and external is done correctly and to help identify problematic areas. Once a faulty integration is discovered, its unit test results can be examined in detail or if it is an external system, further diagnostics on it can be run.</p>
<p>Good judgement on the programmer is key to apply testing at the most convenient levels though on large enterprise systems usually a <strong>combination of unit testing and integration testing</strong> is most appropriate.</p>
<p>Though less well known than Surefire, Maven offers the <a href="http://maven.apache.org/plugins/maven-failsafe-plugin/" title="Maven Integration Testing plugin">Failsafe plugin</a>, designed specifically for integration testing.</p>
<p>It is interesting to note that the name has been chosen to emphasize that failures don&#8217;t stop the Maven lifecycle allowing for gracefully cleaning up any resources used during the testing. As resources can be external it i risky -and rather inelegant- not to clean them up correctly.</p>
<p>According to the Failsafe documentation, it needs to be attached to the integration-test and verify phases (though it seems to work if attached only to the integration-phase). In any case, once invoked it runs through the relevant goals and relevant tests are run.</p>
<h3>Testing FTP and SFTP functionality under Maven</h3>
<p>We have discussed instances of problems where powerful, established plugins are available to do what we want (in this case, testing). However, we need to do something in Maven for where there are no plugins or they are not easy to find. Look it up twice as it is quite likely someone else has solved the problem before though it may be the case no solution exists.</p>
<p>One of such problems is <strong>testing systems that depend on external services such as FTP or SFTP</strong>. Say we have a client that downloads some data off such a server, such as XML files or large binaries and no other interface is available.</p>
<p>A good non-legacy example of such a service is <a href="http://www.youtube.com/t/contentid " title="YouTube Content ID API">YouTube&#8217;s API</a>.</p>
<p>Even though YouTube offers <a href="http://code.google.com/apis/youtube/2.0/developers_guide_java.html" title="YouTube Content ID Java API">programmatic APIs in Java</a> for instance, to use more advanced functionality and for efficient bulk uploading an SFTP interface needs to be used. There are many other examples of such services, using both FTP and SFTP.</p>
<p>Unit tests on the system can be done with mockup objects as usual. However, to do integration testing things get more interesting.</p>
<p>We could, of course, use our YouTube production service to do some integration tests using dummy files, etc. Using production for testing is usually not a very good idea, with potential for disaster. Therefore, using the YouTube production service is not advisable.</p>
<p>Ideally, we should be able to create a mock but fully functional FTP environment, containing exactly the files we need where we can upload and download whatever is necessary and if needed, a small script (say, <a href="http://docs.codehaus.org/display/GMAVEN/Executing+Groovy+Code " title="Executing Groovy from Maven">groovy</a> or something) that simulates whatever it is that YouTube does with your files behind the scenes.</p>
<p>The basic workflow would look like this:</p>
<p><img src="http://dani.calidos.com/wp-content/uploads/2011/08/maven-ftp-server-general.png" alt="FTP Server Maven pluging Phases" title="maven-ftp-server-general" width="603" height="355" class="aligncenter size-full wp-image-369" /></p>
<p>Therefore, we need a <strong>plugin that fires up a FTP server</strong> and points users to specific areas of the target folder. Ideally, it fires up during the pre-integration-test phase and shuts down on the post-integration-test. Easy as a cake.<br />
A google search of &#8216;<a href="http://www.google.com/search?q=maven+ftp+server+plugin" title="Search for FTP server maven plugin">maven ftp server plugin</a>&#8216; yields no significant results and looking up on the <a href="http://maven.apache.org/plugins/index.html" title="Maven official plugin list">official list of plugins here</a>. Also doing a <a href="http://code.google.com/hosting/search?q=maven+plugin+label%3Amaven+ftp&#038;projectsearch=Search+projects" title="Looking up Maven FTP Server plugins on code.google.com">google code search</a> is of no use, either. Lots of stuff to perform FTPs and file transfers but no starting up servers.</p>
<p>Instead of giving up or firing up some server using Ant or even worse, manually(!), we go on and do it the Maven way.</p>
<p>Namely, we develop a plugin that fires up an (S)FTP server on the desired integration test phases.</p>
<p>Firstly, we need a FTP backbone written in Java so it can be integrated easily and of a suitable license. The <a href="http://mina.apache.org/ftpserver/" title="Apache FTP Server">Apache FtpServer</a> is perfect for that purpose. It is a high-performance server based on <a href="http://www.google.com/search?client=safari&#038;rls=en&#038;q=apache+mina&#038;ie=UTF-8&#038;oe=UTF-8" title="Apache MINA project">Apache MINA</a> for I/O and it is ridiculously easy to embed from any Java app. </p>
<h3>Creating the Maven plugin basics</h3>
<p>Firstly, we create a plugin skeleton project using the <a href="http://docs.codehaus.org/display/MAVENUSER/Archetypes+List" title="Maven Archetype plugin listing of templates">Maven Archetype plugin</a>:</p>
<pre name="code">
mvn org.apache.maven.plugins:maven-archetype-plugin:1.0-alpha-7:create -DgroupId=cat.calidos.maven.ftpserver -DartifactId=ftpserver-maven-plugin -DarchetypeArtifactId=maven-archetype-plugin -DarchetypeGroupId=org.apache.maven.archetypes
</pre>
<p>This creates an empty Maven plugin project ready to start adding stuff such as code and tests. We also need to run</p>
<pre name="code">
mvn eclipse:eclipse
</pre>
<p>to create Eclipse settings for the project. We also need to run it whenever we add new dependencies to the POM file so they are also included in the Eclipse world.</p>
<p>Firstly, we add the dependencies for the Apache Ftp server (*):</p>
<pre name="code" class="xml">
	<dependency>
		<groupId>org.apache.ftpserver</groupId>
		<artifactId>ftpserver-core</artifactId>
		<version>1.0.6</version>
	</dependency>
	<dependency>
		<groupId>org.apache.ftpserver</groupId>
		<artifactId>ftplet-api</artifactId>
		<version>1.0.6</version>
	</dependency>
	<dependency>
		<groupId>org.slf4j</groupId>
		<artifactId>slf4j-api</artifactId>
		<version>1.6.1</version>
	</dependency>
	<dependency>
		<groupId>org.slf4j</groupId>
		<artifactId>slf4j-log4j12</artifactId>
		<version>1.6.1</version>
	</dependency>
</pre>
<p>We can find the details on dependencies and versions on a Maven repo such as <a href="http://mvnrepository.com/" title="A large maven repository">MVNrepository</a>. </p>
<p>In this case, we also add the <a href="http://www.slf4j.org/" title="Simple Logging Facade for Java ">Simple Logging Facade for Java</a> &#8216;Log4j&#8217; implementation< so the ftp server can output logs.</p>
<p>This means that whenever we use the maven plugin we should provide a log4j configuration file through the usual methods. Plugin will still work but will complain about the missing configuration. In any case, should we desire to use another logging framework we only need to change the dependency to our chosen implementation artifact.</p>
<h3>Adding our first mojo</h3>
<p>Next, we need to start adding some &#8216;<a href="http://maven.apache.org/plugin-developers/index.html" title="What is a Maven Mojo?">mojos</a>&#8216;, or &#8216;Maven plain Old Java Object&#8217;, which are the fine-grained goals we need to run (or what is the same, tasks that we want Maven to execute). For more information, read the <a href="http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html" title="Intro to the Maven Build Lifecycle">Introduction to the Build Lifecycle</a> article on the official documentation which is very clarifying and chock full of valuable information.</p>
<p>Examining the source of other Maven plugins, we observe a common enough pattern which is to have an abstract superclass with some of the attributes needed by our mojos.</p>
<pre name="code" class="java">
public abstract class AbstractFtpServerMojo extends AbstractMojo {
</pre>
<p>On this class we can add common attributes to our mojos such as the Maven project instance</p>
<pre name="code" class="java">
/** Encompassing maven project
*	@parameter default-value="${project}"
* 	@required
* 	@readonly
*/
protected MavenProject mavenProject;
</pre>
<p>To the attributes we add the revelant annotations which let the Maven runtime inject following the popular <strong>Inversion of Control</strong> pattern. More documentation on the annotations can be found on the <a href="http://maven.apache.org/developers/mojo-api-specification.html" title="Mojo API spec">Mojo API Specification</a>.</p>
<p>Basically, we need one mojo to start the server at the &#8216;pre-integration-test&#8217; phase and another to stop it at the &#8216;post-integration-test&#8217; phase, which gives us this a class hierarchy like this:</p>
<p><img src="http://dani.calidos.com/wp-content/uploads/2011/08/maven-ftp-server-uml1.png" alt="Maven FTP Server mojo classes" title="maven-ftp-server-uml1" width="603" height="355" class="aligncenter size-full wp-image-372" /></p>
<p>Ok, so now we need to take a look at the <a href="http://mina.apache.org/ftpserver/embedding-ftpserver-in-5-minutes.html" title="Apache FTP Server docs">Apache Ftp Server documentation</a> to discover how to embed it.</p>
<p>Fortunately it is pretty straightforward. A server factory instance is created from which a server instance can be created and attached to a specific port. Any such configuration such as adding users, setting up SSL keystores or port and interface attachment are configured using &#8216;<a href="http://mina.apache.org/ftpserver/listeners.html" title="Apache FTP Server configuration classes">listeners</a>&#8216;, which are configuration classes. Multiple listener instances can be set onto the same instance, to allow for multiple interfaces, etc. In the case of this example plugin we aim to configure a subset of all setup possibilities as it is only for integration testing and shouldn&#8217;t be used to deploy production FTP servers. For proper deployment, it can be run and configured fully from the command line or as a Windows service very <a href="http://mina.apache.org/ftpserver/running-ftpserver-stand-alone-in-5-minutes.html" title="Run Apache FTP Server standalone">easily</a>.</p>
<p>Ok, so we add a method to the &#8216;run&#8217; mojo to create the relevant instances</p>
<pre name="code" class="java">
/** Create a server instance with default values
*///////////////////////////////////////////////////////////////////////////////
private void initServer() {

	// add relevant system property variables
	if (systemPropertyVariables!=null) {
		Set<?> propertyNames = systemPropertyVariables.keySet();
		for (Iterator<?> iterator = propertyNames.iterator(); iterator.hasNext();) {
			String propertyName = (String) iterator.next();
			String propertyValue = (String) systemPropertyVariables.get(propertyName);
			getLog().debug("Setting system variable '"+propertyName+"'");
			System.setProperty(propertyName, propertyValue);
		}
	}

	serverFactory = new FtpServerFactory();
	factory = new ListenerFactory();

	// set the port of the listener
	getLog().debug("Using port "+port);
	factory.setPort(port);
	serverFactory.addListener("default", factory.createListener());
	server = serverFactory.createServer();

}	// initServer
</pre>
<p>Firstly, we add any system variables that our POM wants to have added to our environment. This is a common pattern on many plugins and allows plugin users to fine tune system properties on that particular plugin environment. A very important possibility is to be able to configure a custom location of the log4j configuration using the &#8216;log4j.configuration&#8217; system variable. For another example of setting system properties you can look at the excellent <a href="http://wiki.eclipse.org/Jetty/Feature/Jetty_Maven_Plugin#Configuring_Containers" title="Jetty Maven plugin docs">Jetty Maven plugin</a>.</p>
<p>As properties are just key-value pairs of strings, we allow for the Maven injection to inject them defining the appropriate attribute parameter.</p>
<pre name="code" class="java">
/** Additional system property variables (to pass onto tests, etc.)
*	@parameter
*/
protected Map<String,String> systemPropertyVariables;
</pre>
<p>Secondly, we create the factory, listener and server instance. To make use of the more sophisticated features of the Apache Ftp Server we would only need to modify this method a little bit, for instance to allow to bind to a different network interface, etc.</p>
<h3>Adding user management</h3>
<p>Another common enough configuration that is definitely needed is user setup, including password setup, write permissions, home location, simultaneous logins, etc. </p>
<p>Examining the documentation we see a simple yet very flexible <a href="http://mina.apache.org/ftpserver/managing-users.html" title="User management for Apache FTP Server">API to manage users</a>. An interface to an user manager class is provided, &#8216;org.apache.ftpserver.ftplet.UserManager&#8217; and two ready made implementations are available: a properties-based manager and a database-based one. This is very convenient and we could easily have the mojo provide database connection details or a path to a property file. However, we would rather provide configuration details on the POM file itself so all settings are selfcontained in the Maven world.</p>
<p>This means we need a simple factory, user manager and a trivial user class, where all user details are created in Java code.</p>
<p>We start by creating a skeleton factory:</p>
<pre name="code" class="java">
public class SimpleUserManagerFactory implements UserManagerFactory {
</pre>
<p>And fill the necessary methods, in this case, only the &#8216;createUserManager&#8217; method.<br />
We follow by creating a simple User class:</p>
<pre name="code" class="java">
public class User implements org.apache.ftpserver.ftplet.User  {
</pre>
<p>We shouldn&#8217;t really use the Ftp Server User implementation &#8216;BaseUser&#8217; for two reasons: a) it&#8217;s in a private implementation package &#8216;impl&#8217; on ftpserver-core so it can&#8217;t really be used (the interface is public and resides in the ftplet-api library) and b) we want to <strong>populate its details through the POM file</strong> so we need to add appropriate Maven annotations to its attributes.</p>
<p>It is no big deal as it is an easy enough interface to implement, with several key-value pairs, related to the different settings users can have such as maximum number of logins, username, password, etc. We tag the attributes with the Maven annotations and implement all the interface methods.</p>
<pre name="code" class="java">
/** @parameter
*	@required */
protected String name;

/** @parameter
*	@required */
protected String password;
</pre>
<p>Creating the user manager is also pretty straightforward, implementing the UserManager interface of the ftplet API:</p>
<pre name="code" class="java">
public class SimpleUserManager implements UserManager {
</pre>
<p>As a &#8216;repository&#8217; to hold the User data we employ a simple in-memory Map instance:</p>
<pre name="code" class="java">
private HashMap<String, User>	users;
</pre>
<p>The resulting class structure is clear in its intent and purpose:</p>
<p><img src="http://dani.calidos.com/wp-content/uploads/2011/08/maven-ftp-server-um-user.png" alt="Maven FTP Server plugin user management classes" title="maven-ftp-server-um-user" width="603" height="355" class="aligncenter size-full wp-image-373" /></p>
<h3>Testing user management code</h3>
<p>Both the manager and the manager factory classes are pretty much self-contained it is fairly easy to create tests for most of that functionality. For example. in the case of the user manager, on the <a href="http://www.codeguru.com/forum/showthread.php?t=322481" title="Good jUnit setup info">setUp() jUnit method</a> we create a sample environment which we use on each test.</p>
<pre name="code" class="java">
/* (non-Javadoc)
* @see junit.framework.TestCase#setUp()
*///////////////////////////////////////////////////////////////////////////////
protected void setUp() throws Exception {

	super.setUp();

	String adminName = "admin";
	userManager = new SimpleUserManager(adminName,new ClearTextPasswordEncryptor(),false);
	saveUser("demo","demo");
	saveUser("demo2","demo");
	saveUser(adminName,"administrator");

}	// setUp
</pre>
<p>Note that we use the clear text password encryptor both on the test and on the functional code as the passwords are only stored in memory therefore they do not really need to be encrypted and they are in plain view in the POM file anyway.</p>
<p>Using the sample environment we test functionality of the user manager:</p>
<pre name="code" class="java">
/**
* Test method for {@link cat.calidos.maven.ftpserver.users.SimpleUserManager#authenticate(org.apache.ftpserver.ftplet.Authentication)}.
*///////////////////////////////////////////////////////////////////////////////
public void testAuthenticate() {

	loginShouldWork("demo", "demo");
	loginShouldFail("demo", "FAIL");
	loginShouldFail("DOESNTEXIST", "whatever");
	loginShouldWork("admin", "administrator");
	loginShouldFail("admin", "FAIL");

}	// testAuthenticate
</pre>
<p>Methods &#8216;saveUser&#8217;, &#8216;loginShouldWork&#8217; and &#8216;loginShouldFail&#8217; are private convenience methods to aid in testing and make tests more readable, <strong>tests are still code</strong> and should be readable and well-structured like regular functional code.</p>
<h3>Run server mojo</h3>
<p>Next, we add some code to have our configured FTP server instance run:</p>
<pre name="code" class="java">
/** Startup the server and store it on the project properties if possible
*	@throws MojoFailureException
*//////////////////////////////////////////////////////////////////////////////
private void runServer() throws MojoFailureException {

	getLog().debug("About to start FTP server...");

	try {

		server.start();
		getLog().info("FTP server started.");

	} catch (FtpException e) {

		getLog().error("Could not start FTP server...");
		throw new MojoFailureException("Could not start FTP server instance", e);

	}

	Properties properties = null;
	if (mavenProject!=null) {
		properties = mavenProject.getProperties();
		properties.put(FtpServerConstants.FTPSERVER_KEY, server);
	} else {
		throw new MojoFailureException("Can't add ftpserver instance as maven project is null");
	}

}	// runServer
</pre>
<p>The &#8216;start&#8217; method does not block and creates a new thread, where the server code will run and listen for upcoming connections. We also add the instance to the project properties so the server can be stopped gracefully on the &#8216;post-integration-test&#8217; phase.</p>
<p>Also, we do not forget to add the annotation to the &#8216;FtpServerRunMojo&#8217; class that binds the run mojo to the &#8216;pre-integration-test&#8217; phase:</p>
<pre name="code" class="java">
/** Mojo to start the apache FTP server as an integration instance
*	@goal run
*	@phase pre-integration-test
*///////////////////////////////////////////////////////////////////////////////
</pre>
<h3>Stopping the server mojo</h3>
<p>Once our run mojo starts the server, integration tests can be run on the &#8216;integration-test&#8217; phase. Please bear in mind that client POMs can still be configured to run the server on whatever phases they need through XML tweaking.</p>
<p>The stop mojo &#8216;execute&#8217; method is quite straightforward as well:</p>
<pre name="code" class="java">
public void execute() throws MojoFailureException {

	getLog().debug("Stopping FTP server...");
	Properties properties = null;
	if (mavenProject!=null) {
		properties = mavenProject.getProperties();
	} else {
		throw new MojoFailureException("Can't access maven project to stop FTP server (null)");
	}

	if (properties!=null) {

		FtpServer ftpServer;
		try {
			ftpServer = (FtpServer) properties.get(FtpServerConstants.FTPSERVER_KEY);
		} catch (ClassCastException e) {
			throw new MojoFailureException("Context doesn't contain a valid ftp server instance",e);
		}
		if (ftpServer==null) {
			throw new MojoFailureException("Context doesn't contain any ftp server instance");
		}
		if (!ftpServer.isStopped()) {
			ftpServer.stop();
			getLog().info("FTP server stopped.");
		} else {
			getLog().info("FTP server was stopped already");
		}

	} else {
		throw new MojoFailureException("Maven project has null properties",new NullPointerException());
	}

}	// execute
</pre>
<p>After error and sanity checks we retrieve the ftp server instance and stop it. Easy.<br />
Bear in mind that, exceptions during the integration-test phase should be instances of  &#8216;MojoFailureException&#8217; which do not cause the build to die (please check the appropriate documentation on the <a href="http://www.sonatype.com/books/mvnref-book/reference/writing-plugins-sect-custom-plugin.html#writing-plugins-sect-failure" title="Mojo exceptions">Maven reference book</a>).</p>
<p>So, if for instance a single test fails, the other tests can run and the server is gracefully stopped at the end. Using &#8216;MojoExecutionException&#8217; would cause the whole build to stop and if done before the stop mojo has a chance to run the server is not stopped. All probable exceptions on the Maven ftp server plugin are of the type &#8216;MojoFailureException&#8217; as we do not want to stop the whole build if integration tests fail, we report them and it will be up to the client developer to decide what to do.</p>
<h3>Testing the mojos the right way</h3>
<p>Unit testing mojo code is made easier thanks to the &#8216;AbstractMojoTestCase&#8217;</p>
<pre name="code" class="java">
public class FtpServerMojoTest extends AbstractMojoTestCase {
</pre>
<p>This superclass contains some methods to help in testing mojos, mainly methods to read POM files and run mojos. </p>
<p>We also need an FTP client to connect to the running instance. The excellent <a href="http://commons.apache.org/net/" title="Apache Commons Net lib">Apache Commons Net</a> library is ideal for that purpose.</p>
<p>To use it we add the relevant test dependencies to our project POM with a &#8216;test&#8217; scope which means they will only be used on the &#8216;test&#8217; phase and not when the plugin is ran:</p>
<pre name="code" class="xml">
	<dependency>
		<groupId>org.apache.maven.plugin-testing</groupId>
		<artifactId>maven-plugin-testing-harness</artifactId>
		<version>1.2</version>
		<scope>test</scope>
	</dependency>
	<dependency>
	    <groupId>commons-net</groupId>
	    <artifactId>commons-net</artifactId>
   		 <version>3.0.1</version>
    	<scope>test</scope>
    </dependency>
</pre>
<p>So what we want to do is run the FTP server startup method on each test setup and stop it on each test teardown.</p>
<pre name="code" class="java">
/** Read pom and start FTP server
*	@throws java.lang.Exception
*///////////////////////////////////////////////////////////////////////////////
public void setUp() throws Exception {

	super.setUp() ;

	pom = getTestFile("src/test/resources/unit/test-project/pom.xml");
	assertNotNull("Test pom not found",pom);
	assertTrue("Test pom not found",pom.exists());

	port = getFreePort();

	FtpServerRunMojo runMojo = (FtpServerRunMojo) lookupMojo("run", pom);

	// all this will be set on a real project (it's not on the test environment)
	runMojo.serverRoot = new File(PlexusTestCase.getBasedir()+"/target");
	runMojo.port = port;
	runMojo.mavenProject = new MavenProject();
	runMojo.mavenProject.getModel().setProperties(new Properties());
	runMojo.execute();
	ftpServer = (FtpServer) runMojo.mavenProject.getProperties().get(FtpServerConstants.FTPSERVER_KEY);

    ftp = new FTPClient();
    ftp.connect("localhost",port);    

}	// setUp
</pre>
<p>First we call the superclass as it configures stuff we need to call the convenience methods, load up a test pom and find a free port to run the server. Next we lookup the &#8216;run&#8217; mojo and add the relevant data that it needs to start such as the server root, port, container Maven project, etc. All that data is automatically set on a non-test environment but it is not on a test setup. Last on the setup is to connect to the FTP server.</p>
<p>Teardown needs to cleanup the ftp connection and run the stop mojo:</p>
<pre name="code" class="java">
/** Run stop server mojo
* 	@throws java.lang.Exception
*///////////////////////////////////////////////////////////////////////////////
public void tearDown() throws Exception {

	if (ftp.isAvailable()) {
		if (ftp.isConnected()) {
			ftp.disconnect();
		}
	}

	FtpServerStopMojo stopMojo = (FtpServerStopMojo) lookupMojo("stop",pom);

	Properties properties = new Properties();
	properties.put(FtpServerConstants.FTPSERVER_KEY, ftpServer);
	stopMojo.mavenProject = new MavenProject();
	stopMojo.mavenProject.getModel().setProperties(properties);
	stopMojo.execute();

	super.tearDown();	// called last as it dismantles running mojo stuff

}	// tearDown
</pre>
<p>Note we create a Maven project instance to store the running FTP instance which will be stopped by the &#8216;stop&#8217; mojo. We also call &#8216;super.tearDown()&#8217; last to make sure any superclass resources are cleaned up when we are done cleaning up ourselves.</p>
<p>The <strong>test POM</strong> should contain appropriate test data so significant tests can be run, therefore we add different configuration settings to the XML</p>
<pre name="code" class="xml">
<plugin>
	<groupId>cat.calidos.maven.ftpserver</groupId>
	<artifactId>ftpserver-maven-plugin</artifactId>
	<version>1.0</version>
		<configuration>
			<adminUser>
				<name>admin</name>
<password>admin00</password>
			</adminUser>
			<users>
				<user>
					<name>demo</name>
<password>demo</password>
				</user>
				<user>
					<name>disabled</name>
<password>disabled</password>
					<enabled>false</enabled>
				</user>
				<user>
					<name>classes-root</name>
<password>classes-root</password>
					<relativehomeDirectory>./classes</relativehomeDirectory>
				</user>
				<user>
					<name>write-disabled</name>
<password>write-disabled</password>
					<writePermission>false</writePermission>
				</user>

			</users>
		</configuration>
	</plugin>
</pre>
<p>This setup lets us test the administrator user, a regular user, a disabled one, home folders and write-disabled users. There are far more features exposed by the Apache FTP Server though it is not the aim of this test to test them all, just to make a general set of features work as expected. Obviously, to get higher code coverage more tests can be added as needed.</p>
<p>After the POM is ready, we add some unit tests such as the regular user test:</p>
<pre name="code" class="java">
/** Demo user should be able to login
*	@throws SocketException
*	@throws IOException
*//////////////////////////////////////////////////////////////////////////////
public void testDemoUser() throws SocketException, IOException {

    ftp.login("demo", "demo");
	int reply = ftp.getReplyCode();
    assertTrue(FTPReply.isPositiveCompletion(reply));
    assertTrue("Can't login with demo user",ftp.isConnected());

	String filename = "test-file";
	putFile(filename);
	boolean found = findRemoteItem(filename);
	assertTrue(filename+" can't be uploaded",found);

    ftp.disconnect();

}	// testDemoUser
</pre>
<p>We connect, add a test file and ensure it has been uploaded successfully. Both &#8216;putFile&#8217; and &#8216;findRemoteItem&#8217; are convenience methods created on the test class.</p>
<p>Adding more test cases is pretty straightforward, like in the test for readonly users:</p>
<pre name="code" class="java">
/**	User shouldn't have write permissions
*	@throws IOException
*//////////////////////////////////////////////////////////////////////////////
public void testCannotWrite() throws IOException {

	ftp.login("write-disabled", "write-disabled");
	int reply = ftp.getReplyCode();
	assertTrue(FTPReply.isPositiveCompletion(reply));
	assertTrue(ftp.isConnected());

	String filename = "test-file2";
	putFile(filename);
	boolean found = findRemoteItem(filename);
	assertFalse(filename+" can be put on nonwrite permissions user",found);

	ftp.disconnect();

}	// testCannotWrite
</pre>
<h3>Using the plugin</h3>
<p>Doing <strong>integration testing with our completed FTP Server Maven plugin</strong> is pretty straightforward using the &#8216;maven-failsafe-plugin&#8217; to fire up the tests and the &#8216;ftpserver-maven-plugin&#8217; itself to run the FTP server</p>
<pre name="code" class="xml">
<plugin>
	<groupId>cat.calidos.maven.ftpserver</groupId>
	<artifactId>ftpserver-maven-plugin</artifactId>
	<version>1.0</version>

		<configuration>
			<adminUser>
				<name>admin</name>
<password>admin00</password>
			</adminUser>
		<systemPropertyVariables>
			<log4j.configuration>file:target/test-classes/log4j.properties</log4j.configuration>
		</systemPropertyVariables>
	</configuration>

	<!-- start and stop server on the pre and post integration phases -->
	<executions>
		<execution>
			<id>start-ftpserver</id>
			<goals>
				<goal>run</goal>
			</goals>
		</execution>
		<execution>
			<id>stop-ftpserver</id>
			<goals>
				<goal>stop</goal>
			</goals>
		</execution>
	</executions>
</plugin>
</pre>
<p>Not that, unlike in unit testing and the &#8216;maven-surefire-plugin&#8217; the standard test location for the log4j configuration file does not work so we need to specify it on the POM. We also need to specify the goals for the FTP server to startup and shutdown, much along the lines of the <a href="http://maven.apache.org/plugins/maven-failsafe-plugin/usage.html" title="Maven Failsafe plugin usage docs">Maven Failsafe plugin</a> itself.</p>
<p>If any of the integration tests fails the stop goal is still ran and the server shuts down gracefully. </p>
<p>Additionally, if running the FTP server is needed on phases other than the integration testing ones the goals be attached to the relevant phases through our client POM.</p>
<h3>Wrapping up: creation of an FTP server plugin</h3>
<p>We have identified a need of using a fully functional FTP and SFTP server in integration testing using Maven. Looking up available plugins on the Web does not yield any already available plugins. We have gone ahead and built a plugin from scratch using the Apache FTP Server opensource library.</p>
<p>You can download the source code of version 1.0 of the <a href="/img/2011/ftpserver-maven-plugin-1.0-sources.zip" title="FTP Server Maven plugin source">maven-ftpserver-plugin</a> as well as a <a href="/img/2011/ftpserver-maven-plugin-sample-1.0-sources.zip" title="FTP Server Maven Plugin usage sample">sample client project</a>. Enjoy and comments are welcome.</p>
<p><em>(*) Between completing the code and writing the article Apache FtpServer came out with a new release (1.0.6). Thanks to Maven and the fair amount testing it was ridiculously easy to upgrade the project, just changed the dependency numbers on the pom file and ran a maven build.<br />
</em></p>
]]></content:encoded>
			<wfw:commentRss>http://dani.calidos.com/2011/08/15/building-an-ftp-server-maven-plugin-from-scratch/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>100 push-ups 2.0</title>
		<link>http://dani.calidos.com/2011/04/25/100-push-ups-2-0/</link>
		<comments>http://dani.calidos.com/2011/04/25/100-push-ups-2-0/#comments</comments>
		<pubDate>Mon, 25 Apr 2011 10:52:00 +0000</pubDate>
		<dc:creator>dani</dc:creator>
				<category><![CDATA[Catalan]]></category>
		<category><![CDATA[Fitness]]></category>
		<category><![CDATA[catalan]]></category>
		<category><![CDATA[fitness]]></category>
		<category><![CDATA[gtd]]></category>
		<category><![CDATA[push-ups]]></category>
		<category><![CDATA[total-body-movement]]></category>

		<guid isPermaLink="false">http://dani.calidos.com/?p=343</guid>
		<description><![CDATA[Els programes de fitness són sovint complicats. Es composen de multitud d&#8217;exercicis força difícils, amb risc de lesió si no es fan correctament i a sobre repartits entre diversos dies, complicant-ne el seguiment i l&#8217;execució. Definitivament representen una barrera d&#8217;entrada &#8230; <a href="http://dani.calidos.com/2011/04/25/100-push-ups-2-0/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Els programes de fitness són sovint complicats. Es composen de multitud d&#8217;exercicis força difícils, amb risc de lesió si no es fan correctament i a sobre repartits entre diversos dies, complicant-ne el seguiment i l&#8217;execució. Definitivament representen una barrera d&#8217;entrada intimidatòria pels aventurers de la bona forma física.</p>
<p><img alt="Portada 100 push-ups" src="/img/2011/100pushups.png" title="Portada 100 push-ups" class="alignnone" width="401" height="316" /></p>
<p>Per això m&#8217;encanta el programa de 100 push-ups en 7 setmanes de Steve Speirs.<br />
La idea bàsica del programa és arribar a fer un centenar de push-ups a l&#8217;estil militar si es segueix el programa al peu de la lletra. D&#8217;entrada sembla un repte &#8216;impossible&#8217; pels mortals més comuns (un servidor inclòs).</p>
<p>La premissa bàsica és que un push-up és un exercici en la línia de &#8216;<a href="http://www.youtube.com/watch?v=Pv5PsOl2TZE">full body movement</a>&#8216;, on es mou tot el cos i s&#8217;involucren el màxim de grups musculars i articulacions. Es creu que els exercicis d&#8217;aquest tipus són molt beneficiosos i presenten un rendiment superior que el de les típiques màquines de musculació o els exercicis &#8216;localitzats&#8217; en una sola part del cos. Córrer n&#8217;és un dels exemples més clàssics.</p>
<p>Un push-up involucra els pectorals, els tríceps (els grans oblidats), deltoides, serratus anterior (músculs de l&#8217;esquena situats sota la part superior dels braços), els músculs abdominals, glutis i bíceps. En el cas d&#8217;aquests últims amb els push-ups tradicionals no es treballen gaire i cal fer alguna variant si es vol potenciar-los. La diferència en el nivell de treball dels bíceps i tríceps és significativa pel fet que els tríceps comformen el 60% de la massa muscular de la zona superior dels braços. Cal pensar que s&#8217;acostuma a abusar del treball amb els bíceps per raons estètiques, cosa que pot causar desequilibris de tota mena.</p>
<p>Per seguir el programa, primerament es fa un test de quantes flexions es poden fer seguides, sense parar. Depenent de la quantitat final -jo en vaig fer 20-, es comença amb un programa concret o un altre. En el meu cas em toca el &#8216;Intermediate 2&#8242;. Malgrat que amb un push-up més ja passaria al &#8216;Advanced 1&#8242;, millor no precipitar-se! Fins i tot hi ha un programa pels qui no són capaços de fer cap push-up o només uns quatre o cinc.</p>
<p>Un cop fet el test i seleccionat el programa només cal anar seguint els passos cada dia. L&#8217;estructura principal gira al voltant de la setmana o almenys de cicles iteratius incrementals de set dies. Quatre dies de descans alternats amb tres dies d&#8217;exercici.</p>
<p>L&#8217;exercici es basa en l&#8217;escalfament, uns quants sets de push-ups amb un descans d&#8217;un minut entre cadascun i els estiraments finals. En un quart d&#8217;hora o vint minuts es pot completar tranquil·lament, escalfament i estiraments inclosos.</p>
<p>Avui em toca descans i demà toca &#8216;warm up, 11, 14, 11, 11, 16+, stretch (Intermediate 2, week 3)&#8217;, que són com a mínim 63 push-ups, no està del tot malament.</p>
<p>Per fer el seguiment es pot fer servir qualsevol tècnica, un paper, el llibre de Steve Speirs, GTD, una agenda&#8230; Jo faig servir el <a href="http://www.rememberthemilk.com/">Remember The Milk</a> que és un servei de GTD boníssim.</p>
<p>Al durant la setmana final de cada programa es poden fer sèries impresionants de més de 22 o 24 push-ups i en el cas del Intermediate 2 hi ha una traca final de més de 60!</p>
<p>Un cop completat el programa la idea és descansar dos o tres dies i intentar fer 100 push-ups seguits. Sembla impossible, no?</p>
<p>Per més detalls sobre el programa hi ha diverses opcions, primerament hi ha el site <a href="http://hundredpushups.com/index.html">One Hundred Push ups</a>, on podem trobar el programa, diversos recursos, programes alternatius, merxandatge i molts <a href="http://hundredpushups.com/didthehundred.html">testimonials</a>, inclòs el d&#8217;algun <a href="http://timbisenterthelinux.com.ar/estoy-en-forma/">linuxero</a>, hehe.</p>
<p>També hi ha el <a href="http://www.amazon.co.uk/Weeks-100-Push-ups-Strengthen-Consecutive/dp/1569757070/ref=sr_1_1?s=books&#038;ie=UTF8&#038;qid=1303727979&#038;sr=1-1">llibre</a> (el programa exacte que segueixo), escrit per l&#8217;ideòleg del programa. Els més moderns poden provar l&#8217;aplicació per <a href="http://itunes.apple.com/us/app/hundred-pushups/id301174591?mt=8">iPhone</a>.</p>
<p>A veure si us animeu!</p>
]]></content:encoded>
			<wfw:commentRss>http://dani.calidos.com/2011/04/25/100-push-ups-2-0/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Nokia, Google and Microsoft, without any options in the mobile arena</title>
		<link>http://dani.calidos.com/2011/03/27/nokia-google-microsoft-without-any-options/</link>
		<comments>http://dani.calidos.com/2011/03/27/nokia-google-microsoft-without-any-options/#comments</comments>
		<pubDate>Sun, 27 Mar 2011 21:08:32 +0000</pubDate>
		<dc:creator>dani</dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[business]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[nokia]]></category>
		<category><![CDATA[RIM]]></category>
		<category><![CDATA[smartphones]]></category>
		<category><![CDATA[strategy]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://dani.calidos.com/?p=324</guid>
		<description><![CDATA[Google, Microsoft and Nokia have something in common: they had little choice in some of their latest strategic moves in the mobile arena, maybe their biggest moves in a long, long time. Unusual for such giants, eh? <a href="http://dani.calidos.com/2011/03/27/nokia-google-microsoft-without-any-options/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In this post I argue that Google, Microsoft and Nokia have something in common: they had little choice in some of their latest strategic moves in the mobile arena, maybe their biggest moves in a long, long time. Unusual for such giants, eh?</p>
<p>For the sake of drama and structure I will go from the most obvious to the slightly less evident and finish with the most subtle of the three.</p>
<p><img alt="Microsoft, Google, Nokia" src="/img/2011/trio-little-choice.png" title="Microsoft, Google, Nokia" class="alignnone" width="489" height="282" /></p>
<p/>
<p/>
<p><strong>Firstly, there is Microsoft.</strong></p>
<p>It is common knowledge that the old boys from Redmond are in deep trouble in the mobile arena (and still are). After being a major player in the mobile smartphone arena for quite a long time it has gradually become a so-so player, being met by some skepticism by users and critics alike.</p>
<p>Even though Windows Phone 7 received <a href="http://www.engadget.com/2010/10/20/windows-phone-7-review/">decent reviews</a> it feels like too little and definitely too late.</p>
<p>The Windows Phone 7 rollout still feels too <a href="http://www.winsupersite.com/article/paul-thurrotts-wininfo/Windows-Everywhere-Wake-Up-Microsoft-It-s-2011.aspx">corporate</a> to me and still part of a lukewarm strategy. </p>
<p>Yeah but Microsoft has conquered or at least made a good dent on other markets before, even if just by brute force, yes? (read <a href="http://www.afterdawn.com/news/article.cfm/2010/05/29/ps3_quarterly_market_share_jumps_to_31_percent">XBOX</a>).</p>
<p>So why would a juggernaut like Microsoft be constrained in its long-term strategy? Shouldn&#8217;t be.</p>
<p>Well, it&#8217;s the systems, stupid.<br />
If anything, Apple has taught the industry one thing with the iPod, iPhone and lately with the iPad. Consumers love <a href="http://en.wikipedia.org/wiki/System">SYSTEMS</a>.</p>
<p>Consumers don&#8217;t like loosely coupled devices. Consumers don&#8217;t like replacing or upgrading components. Consumers don&#8217;t like lengthy boot sequences. Consumers don&#8217;t like invasive firmware installations. Consumers don&#8217;t like the software provider plus OEM combination. Maybe they did in the beginning of the 90&#8242;s. We ain&#8217;t in the 90&#8242;s anymore. XBOX, though successful, has been targeted at hardcore gamers rather than casual ones up until the Kinect.</p>
<p>On top of that Microsoft has <a href="http://www.betanews.com/joewilcox/article/Somebody-notify-the-next-of-kin-Microsoft-KIN-is-dead/1277937674">learned</a> something on its own, <a href="http://www.bloomberg.com/news/2011-03-14/microsoft-said-to-stop-releasing-new-zune-models-as-demand-ebbs.html">it doesn&#8217;t know how to build consumer SYSTEMS at all</a>.</p>
<p>Therefore, to get itself out of the hole, Microsoft considered its options.</p>
<p>Acquisition of a successful company just to go on and destroy it in the process was ruled out, lest it turn into another disaster.</p>
<p>Lesson learned and any acquisitions ruled out, Microsoft then took a look at the OEM market… Err, in the case of MS, it meant HTC, <a href="http://www.mobileburn.com/news.jsp?Id=6424">builder of the 80% of cell phones bearing Microsoft&#8217;s mobile O</a>S (at least prior the 7th version). Out of 50 partners!</p>
<p>Well, a simple Google search for Android and HTC is quite revealing. HTC didn&#8217;t jump ship, not exactly. But it started to be <a href="http://www.andro-phones.com/htc.html">really busy building handsets with that OS</a>.</p>
<p>Well, considering Android had been in the market for a while, a mature product, consumers liking it, with a plethora of apps and -most importantly- being FREE, what do you expect? Considering that MS has been known to thoroughly <a href="http://www.informationweek.com/blog/main/archives/2007/08/microsoft_has_i.html">screw</a> its partners from time to time., who can blame HTC?</p>
<p>Surely, HTC has hedged its bets and is only too <a href="http://www.htc.com/uk/press.aspx?id=147164&#038;lang=1033">happy</a> to license to MS and adopt a wait-and-see attitude to it to see if it sticks and to exploit slow IT corporate policies that still mandate Windows-Everywhere(™).  The good old leverage from the fading age of Windows was gone though and Microsoft would feel like second best here.</p>
<p>Choice taken away: traditional OEMs were out.</p>
<p>To add icing on the cake, it would seem that Microsoft had little choice but to license the ARM architecture, surely watched closely by its mobile hardware OEMs who have perceived it as yet another sword hanging over their little necks. A sword that would materialise as Microsoft mobile hardware. Uh-oh. Again, Microsoft has had to take some eggs from the software-only basket and put them on the systems one though only as a last resort (see Kin fiasco).</p>
<p>No pure-OEM model then. No acquisitions. Definitely not Android. SONY? You gotta be kidding. No Microsoft hardware (yet). Samsung maybe? <a href="http://galaxys2.samsungmobile.com/">Nay</a>.</p>
<p>Um&#8230;</p>
<p>It had to be Nokia then. It&#8217;s smartphone marketshare in decline, Microsoft couldn&#8217;t go anywhere else.</p>
<p/>
<p/>
<p><strong>Which leads nicely to the next big boy, Nokia itself.<br />
</strong></p>
<p>Nokia is a giant. Massive with customers, it has created remarkable legendary mobile designs. However, its fortunes -or at least its marketshare lead- got reversed and were showing a worrying <a href="http://clients.needhamco.com/Research/Documents/INDN149363.pdf">trend</a>.</p>
<p>The new CEO <a href="http://conversations.nokia.com/2011/02/11/open-letter-from-ceo-stephen-elop-nokia-and-ceo-steve-ballmer-microsoft/">put it very well</a> himself, the company is in dire straits indeed, at least in the long term.</p>
<p>Nokia also considered its options.</p>
<p>Nokia understands systems and consumers very well, probably much more than Microsoft does or has ever done. With that in mind, Elop and senior managers understood that Symbian is a thing of the past that. Meego <a href="http://www.slashgear.com/nokia-n9-00-reportedly-axed-as-meego-flails-09131996/">wasn&#8217;t ready</a> and perhaps would never be good enough.</p>
<p>But, wait? A company the size of Nokia has lots of engineering talent! Yes, but also lots of middle managers and lacklustre leadership, if one is to believe Nokia&#8217;s top brass.</p>
<p>Therefore, culling the company of useless meddlers and taking the time to isolate a dedicated, motivated and driven team to push Meego (much like what Palm managed to do with its WebOS) up to scratch would take time, too long. If I remember correctly, it took Palm the better part of two years or more to get WebOS near 1.0-status and that is an heroic feat. Time though, is not something Nokia had available. Option out.</p>
<p>Acquisition? Nokia doesn&#8217;t strike me as an <a href="http://www.nokia.com/about-nokia/financials/acquisitions">acquisition-crazy company</a>. </p>
<p>Firstly, a nimble startup would understandably have a hard time integrating into a <a href="http://press.nokia.com/2010/04/22/nokia-q1-2010-net-sales-eur-9-5-billion-non-ifrs-eps-eur-0-14-reported-eps-eur-0-09/">company of 12.000+ employees</a>.</p>
<p>Secondly, while the Trolltech acquisition had some technical merit, it was completed in 2008 and Nokia has&#8217;t really made Qt onto the big promised paradise it was intented to. And they have had plenty of time to do it. </p>
<p>And finally, who to buy? RIM? Are you kidding? Making the company bigger and having a huge corporate cultural clash to boot?!? And getting RIM&#8217;s <a href=" http://www.businessinsider.com/rim-ceo-dive-into-mobile-2010-12">loony CEO</a>(s) onboard? </p>
<p>Nay, purchasing its way out of trouble, choice taken away.</p>
<p>Which lead Nokia to consider Android.</p>
<p>One can imagine Nokia seeing Android as the forbidden fruit of sin. Juicy, tempting, free for the taking… and ultimately damning.</p>
<p>Oh, there is the <a href="http://fosspatents.blogspot.com/2011/03/googles-android-faces-serious-linux.html">legal swamp</a>. Before taking a bite out of the fruit, Nokia must have had it&#8217;s lawyer legions take a good look at it.</p>
<p>If that was not to scare the Nokia strategist what would?</p>
<p>Well, I would argue that the real reason is freedom. Freedom to differentiate. As the Symbian guys <a href="http://www.allaboutsymbian.com/features/item/12622_Understanding_Nokias_smartphon.php">put it</a> &#8220;[…] surrender too much of the value and differentiation ability, most obviously in services and advertising, to Google.&#8221; Exactly. Nokia would play on the same field as all the other OEM. Bummer, from leading systems developer down to mere squabbling OEM.</p>
<p>Surely Nokia had been following what happened to Motorola and the <a href="http://www.eweek.com/c/a/Mobile-and-Wireless/Skyhook-Sues-Google-for-Interference-Patent-Infringement-745676/">Skyhook guys</a>.</p>
<p>Apparently, both Motorola and &#8216;Company X&#8217; (believed to be Samsung) have been prevented by Google from shipping handsets bearing its location technology. Remeber <a href="http://ca.reuters.com/article/technologyNews/idCATRE72K67320110321">Navteq</a>? Ever heard of Nokia maps?</p>
<p>Jump onto the Android bandwagon and kiss goodbye to all that.</p>
<p>So Android being out what was left as an option? <a href="http://www.computerworld.com/s/article/9209259/Microsoft_to_pay_out_billions_as_part_of_Nokia_deal">A company in desperate need</a>? </p>
<p>Microsoft.</p>
<p>Which leads to the idea of Google having courted Nokia precisely for many of the reasons Microsoft &#8216;bought&#8217; them in the first place.</p>
<p/>
<p/>
<p><strong>Finally, Google is the third big one having run out of options on some of its most strategic options.<br />
</strong><br />
Consider the official gospel on why Google created Android and released it to the wild. Well, <a href="http://www.tomshardware.com/news/Honeycomb-Source-Code-Distribution-Delayed-Not-Ready,12462.html">most of it, anyway</a>.</p>
<p>According to Vic Gundotra from Google:</p>
<p>&#8220;If Google didn&#8217;t act, it faced a draconian future where one man, one phone, one carrier were our choice. That&#8217;s a future we don&#8217;t want.&#8221;</p>
<p>Sounds chivalrous and following the &#8216;Don&#8217;t be evil&#8217; mantra. Google released Android to save us all from that bleak future.</p>
<p>Well, it&#8217;s not true.</p>
<p>Consider Google&#8217;s business model. It revolves around advertising and to do well in advertising you need eyeballs, lots of them. Furthermore, to do very well you need targeted eyeballs, that is, to show the right adverts to the right people, to maximise chances of these people hitting the ads.</p>
<p>Google&#8217;s business model elevator pitch: person would like to get a service or product on the Web. Cool, she fires up Google on her desktop or laptop and does a search for the terms she thinks will help her find that product or service. Maybe clicks on the ads, maybe finds what she is looking for, maybe not. Bonus points: does more searches through Google, refining the terms (translation: getting more targeted ads), finally finds what she is looking for. This happens millions of times. Google makes tons of money. </p>
<p>Whereas if that same person would like to get a service or product on her iPhone, the story is completely different. Cool, she fires up the App Store app, does a search or browses the categories. Looks at the top charts, reads the reviews and how many stars the candidate solutions have, ponders wether to pay or get a free app, etc. Person chooses app and installs it. Google gets zero money. Zaroo, zip, nada, nothing.</p>
<p>There are a few things that need to be considered:</p>
<ul>
<li>Not all services are available through the App Store and probably will never be a 100%, but there are zillions of apps (read, services) waiting to be downloaded.
</li>
<li>People trust Google to deliver good search results but how to compare one result from the other can basically only be done by the rank itself or by clicking on the link and spending sometime on the site. The App Store offers a simplified interface allegedly easier the average consumer (ranks, reviews, stars, etc.).
</li>
<li>People trust the App Store as well, it has never allowed malware on people&#8217;s devices.
</li>
<li>Apple is very careful and vocal about not having any influence on the ranking, like, <a href="http://www.techeye.net/internet/google-tampers-with-search-results-to-rank-itself-first-report">erm</a>, Google.
</li>
<li>To get iPhone apps, geeks will do research on Google and the Web. Will look for extended reviews, comparisons and specialised sites. Consumers just use the App Store.
</li>
</ul>
<p>Google knew that smartphones and later tablets would be the devices the mass market consumer will use to access the Internet. iOS was looking good and demolishing the competition at the time. It seems to be doing the same now.</p>
<p>The App Store is a &#8216;Google search&#8217; replacement.</p>
<p>I would say that Apple wasn&#8217;t expecting it to become so successful. I would add that Apple didn&#8217;t set out to build a Google search replacement when the App Store was built. Apple engineers and product managers only wanted to create a better experience for consumers than googling vague terms, shuffling through specialised review sites, getting malware off dubious websites, etc. Google is collateral damage. </p>
<p>Google knew it had to act, very fast and with very decisive steps. Apple&#8217;s competition was in shambles and couldn&#8217;t get their stuff together for the life of them. Microsoft Windows Mobile 6.x was crap and any real future releases years into the future, RIM was -is- a shadow of its former self and Palm was on its last legs. Google couldn&#8217;t wait on them.</p>
<p>Android was born and released for free. Had to be. Google didn&#8217;t have any other choice. What they really imagined was a mobile future sans Android, where Apple would rule. Imagine if Android didn&#8217;t exist what the marketshare of Apple would be on smartphones today and Google wouldn&#8217;t be able to continue making money on it. That is the future Google didn&#8217;t want.</p>
<p>A corporate strategy is about having a vision and making it happen and the three giants have <a href="http://www.imdb.com/title/tt0265086/quotes">lost the initiative</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://dani.calidos.com/2011/03/27/nokia-google-microsoft-without-any-options/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>St Wolfgang, Àustria</title>
		<link>http://dani.calidos.com/2010/09/29/st-wolfgang-austria/</link>
		<comments>http://dani.calidos.com/2010/09/29/st-wolfgang-austria/#comments</comments>
		<pubDate>Wed, 29 Sep 2010 12:24:20 +0000</pubDate>
		<dc:creator>dani</dc:creator>
				<category><![CDATA[Catalan]]></category>
		<category><![CDATA[Food]]></category>
		<category><![CDATA[Random]]></category>
		<category><![CDATA[Austria]]></category>
		<category><![CDATA[lake]]></category>
		<category><![CDATA[restaurant]]></category>
		<category><![CDATA[tourism]]></category>

		<guid isPermaLink="false">http://dani.calidos.com/?p=309</guid>
		<description><![CDATA[Menció especial d&#8217;aquestes vacances pel racó austríac de St. Wolfgang im Salzkammergut, prop de St. Gilgen. Localització genial totalment recomanable més enllà de les visites més típiques com pot ser Vienna, la zona del Danubi, Salzburg, etc. La manera més &#8230; <a href="http://dani.calidos.com/2010/09/29/st-wolfgang-austria/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Menció especial d&#8217;aquestes vacances pel racó austríac de <a href="http://maps.google.com/maps?f=q&amp;source=s_q&amp;hl=en&amp;geocode=&amp;q=St.+Wolfgang+im+Salzkammergut&amp;sll=37.0625,-95.677068&amp;sspn=38.144864,74.882813&amp;ie=UTF8&amp;hq=St.+Wolfgang+im+Salzkammergut&amp;hnear=&amp;radius=15000&amp;t=h&amp;z=12">St. Wolfgang im Salzkammergut</a>, prop de <a href="http://maps.google.com/maps?f=q&amp;source=s_q&amp;hl=en&amp;geocode=&amp;q=St.+Gilgen&amp;sll=47.738728,13.447483&amp;sspn=0.126758,0.292511&amp;ie=UTF8&amp;hq=&amp;hnear=St+Gilgen,+Salzburg,+Austria&amp;ll=47.767022,13.364182&amp;spn=0.12092,0.292511&amp;t=h&amp;z=12">St. Gilgen</a>.</p>
<p>Localització genial totalment recomanable més enllà de les visites més típiques com pot ser Vienna, la zona del Danubi, Salzburg, etc.</p>
<p><img alt="Cool St Wolfgang photo" src="http://dani.calidos.com/img/2010/St-Wolfgang.jpg" title="Cool St Wolfgang photo" class="alignnone" width="90%" /></p>
<p>La manera més fàcil d&#8217;arribar és via St. Gilgen i és recomanable agafar el ferri que et porta pel llac Wolfgangsee i va parant pels diversos poblets. Mentres degustes una cerveseta dins del ferri vas escoltant com t&#8217;expliquen curiositats de la zona primer en alemany i després en un anglès molt correcte. Bé, almenys fins que s&#8217;en cansen i es passen a l&#8217;alemany directament&#8230; així et pots imaginar què diuen i l&#8217;experiència es torna encara més estimulant. El ferri és molt còmode i diposa de taules on recuperar forçes i disfrutar del viatge.</p>
<p>De fet, això es repeteix força en les localitzacions Austríaques menys cèntriques -que no menys turístiques- on et trobes amb una gran quantitat de menús exclusivament en la llengua germànica i res de res en anglès. Una mica d&#8217;&#8221;aventura&#8221; no fa mal.</p>
<p>Pel que sembla, St. Wolfgang és famós per l&#8217;hotel del &#8216;Cavall Blanc&#8217;, regentat per la mateixa família desde el 1712 i escenari de la òpera &#8216;White Horse Inn&#8217;, de <a href="http://en.wikipedia.org/wiki/Ralph_Benatzky">Ralph Benatzky</a>. Segons diuen és una peça &#8220;mundialment famosa&#8221;&#8230; veurem quan arriba al Liceu.</p>
<p>En sí el poble és força petit tot i que té unes quantes perles amagades. Per exemple, hi ha una col·lecció de nines força gran muntada per un senyor força friki, on destaca la immensa quantitat i varietat de Barbies. Les Barbie islàmiques, orientals i indies destaquen especialment.</p>
<p>Tampoc us perdeu el típic pub de poble amb la típica disco al costat. Al pub es poden beure còctels d&#8217;allò més bons (recomanat el &#8220;Swimming Pool&#8221;) i observar com els locals consumeixen unes quantitats gens despreciables d&#8217;alcohol.</p>
<p>Pel que fa a l&#8217;allotjament, imprescindible el petit hotel &#8216;<a href="http://www.hupfmuehle.at/">Hupfmuehle</a>&#8216;, al costat d&#8217;un rierol amb cascada inclosa que va a desembocar al llac. Hi ha una pujadeta important però quan s&#8217;arriba a dalt segurament us trobareu al patriarca de la família que el regenta que us estarà esperant&#8230; D&#8217;aquest pal, vaja. Moltes de les habitacions donen directament a la cascada i el so és tant relaxant que et quedes adormit en un plis plas. Mentres esperes l&#8217;hora de sopar et pots estar a la terrassa fent un vermutet.</p>
<p><img alt="Hotelet Upfmuehle" src="http://dani.calidos.com/img/2010/hupfmuehle2.png" title="Hotelet Upfmuehle" class="alignnone" width="390" height="221" /></p>
<p>El menú és força curiós pel fet que és molt curt: sopa o amanida de primer i de segon només hi ha peix, truita de riu o una varietat local. Quan has triat el pesquen i el preparen al moment. Com era d&#8217;esperar és deliciós.</p>
<p>L&#8217;endemà cal recuperar-se de la ressaca generada al pub del poble i deixar-se caure pel restaurant <a href="http://www.josephs.at/">Joseph&#8217;s</a>. No és precisament barat però tampoc és desproporcionat pel servei i la qualitat. El menú és exclusivament en alemany i està escrit en una pissara mòbil que et porta el cambrer cosa que dóna molta vidilla. Hi ha menú degustació o pots triar els plats que vols. Les làmines de vedella amb verdures són de lo millor que he tastat mai. La selecció de vins, xampany, caves i licors és molt extensa i també val com a vinoteca o sigui que si un vi t&#8217;ha agradat en pots comprar una ampolla per potser acabar-la a l&#8217;hotel amb més intimitat?</p>
<p>Resumint, cal fugir dels llocs més habituals i explorar aquests raconets genials que ens regala Europa&#8230; No ens en penedirem!</p>
]]></content:encoded>
			<wfw:commentRss>http://dani.calidos.com/2010/09/29/st-wolfgang-austria/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Templating the OSGi way with Freemarker</title>
		<link>http://dani.calidos.com/2010/08/11/templating-the-osgi-way-with-freemarker/</link>
		<comments>http://dani.calidos.com/2010/08/11/templating-the-osgi-way-with-freemarker/#comments</comments>
		<pubDate>Wed, 11 Aug 2010 19:52:08 +0000</pubDate>
		<dc:creator>dani</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[bundles]]></category>
		<category><![CDATA[freemarker]]></category>
		<category><![CDATA[osgi]]></category>
		<category><![CDATA[templating]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://dani.calidos.com/?p=285</guid>
		<description><![CDATA[After some well-deserved rest the OSGi components on the server series is back with a vengeance and a somewhat independent post. For some background please check the other posts in the series. A common feature of Web applications is the &#8230; <a href="http://dani.calidos.com/2010/08/11/templating-the-osgi-way-with-freemarker/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>After some well-deserved rest the OSGi components on the server series is back with a vengeance and a somewhat independent post. For some background please check <a href="http://dani.calidos.com/category/computing/java/">the other posts in the series</a>.</p>
<p>A common feature of Web applications is the need to output structured content, be it XML, XHTML markup, JSON or many others. A number of technologies is used to do that but few seem to be that dynamic, usually only reloading templates when they change or loading them from URLs. Surely we can leverage OSGi to make things more interesting&#8230;</p>
<p>Therefore we should be following the OSGi dynamic philosophy as much as possible, exploiting the features made available by the framework such as dynamic discovery, services, bundle headers and the lot.</p>
<p>In the case of our cache app we are violating quite a few basic design principles by having the format embedded in the java code. So we should as well use a template separate from the code and if possible reuse some existing well-known templating engine from somewhere.</p>
<p>Given these basic design principles let&#8217;s get started.</p>
<p>Firstly, we need a robust and flexible templating engine. We select the mature <a href="http://freemarker.sourceforge.net/">Freemarker</a> engine which is reasonably speedy and has the power and flexibility we want. Make sure you check out the <a href="http://freemarker.sourceforge.net/docs/app_license.html">license</a>, of course.</p>
<p>We could stop at putting the library JAR in a bundle and package it so it can be used by any other bundle and that is what we do to be able to use it in OSGi. That however doesn&#8217;t exploit many of the nicer OSGi capabilities so we will create another bundle called &#8216;com.calidos.dani.osgi.freemarker-loader&#8217;.</p>
<p>What we want is to allow bundles to carry templates inside them and have our freemarker-loader templating bundle discover them automagically. This is the same technique that the Spring dynamic modules use and you can find more info <a href="http://eclipse.dzone.com/articles/osgi-42-extender-pattern-and">here</a>. The mechanism is described in this diagram:</p>
<p><img alt="OSGi freemarker templating diagram" src="http://dani.calidos.com/img/2010/osgi-08/osgi-template-components.png" title="OSGi freemarker templating diagram" class="alignnone" width="429" height="434" /></p>
<p>That is easy enough with a BundleTracker and a BundleTrackerCustomizer implementation. The BundleTracker class tracks bundles being added to the environment like this:</p>
<pre name="code" class="java">
tracker = new BundleTracker(context, Bundle.RESOLVED, templateTracker);
tracker.open();
</pre>
<p>With this snippet the tracker instance will look for bundles in the RESOLVED state (which lets us track fragments). The &#8216;templateTracker&#8217; object is an instance of BundleTrackerCustomizer and will receive callbacks whenever bundles are added to the environment.</p>
<p>For instance, when a bundle is added we check for a special header in the bundle which tells us what is the relative path of available templates in the bundle being resolved:</p>
<pre name="code" class="java">
public Object addingBundle(Bundle bundle, BundleEvent event) {

// we look for the header and act accordingly
String templatesLocation = (String) bundle.getHeaders().get(TEMPLATE_HEADER);
if (templatesLocation!=null) {

	Enumeration<URL> bundleTemplates = bundle.findEntries(templatesLocation, "*.ftl", true);
	HashSet<URL> templatesFromAddedBundle = new HashSet<URL>();
	while (bundleTemplates.hasMoreElements()) {

		URL templateURL = bundleTemplates.nextElement();
		addTemplate(bundle, templateURL,templatesLocation);
		templatesFromAddedBundle.add(templateURL);

	}

	templatesOfEachBundle.put(bundle.getBundleId(), templatesFromAddedBundle);

}
return null;

}	// addingBundle
</pre>
<p>An interesting method being used here is &#8216;findEntries&#8217; which loads all the entries in the provided templates folder and lets us add them to our holding structure. We also take care to implement the methods to remove the templates and update them accordingly whenever bundles are updated or unloaded from the environment.</p>
<p>Having TEMPLATE_HEADER with a value of &#8216;Freemarker-Templates&#8217; means that bundles having a header such as <code>Freemarker-Templates: /templates</code> will have any templates within that folder (<i>please note that the &#8216;/templates&#8217; bit is not added to template URLs!</i>).</p>
<p>The next thing we need to do is make the loaded templates available to the environment. To do that we make a freemarker Configuration object accessible as an OSGi service object. That Configuration instance is the main object Freemarker to load and use templates and has an interesting mechanism to override its template loading mechanism we use to make available our OSGi environment templates.</p>
<pre name="code" class="java">
freemarkerConfig.setTemplateLoader( new URLTemplateLoader() {

@Override
protected URL getURL(String url) {
Stack<TemplateEntry> templateStack = templates.get(url);
if (templateStack!=null) {
	TemplateEntry templateStackTop = templateStack.peek();
	if (templateStackTop!=null) {
		return templateStackTop.getTemplateURL();
	}
	return null;
}
return null;
}

});
</pre>
<p>The service Configuration object is set with a template loader inner class that uses our template holding objects to retrieve templates stored in our OSGi context. Cool.</p>
<p>This also allows us to effectively disable the template refreshing cycles that Freemarker does by default (allegedly making it slightly more efficient). Now we only need to refresh a bundle containing the templates to get the new version. This can be modified by using the appropriate methods on the Configuration service of course. (<i>There is another method explained later</i>).</p>
<p>An interesting feature we can add to exploit the dynamic nature of OSGi is to make templates available in a stack. This means different bundles can dynamically overwrite templates by the same name. Moreover, once a template is removed the previous version becomes available. This can be used to make temporary changes to templates to add or remove diagnostics information, test new templates temporarily, etc.</p>
<p>We do that using a Stack of TemplateEntry objects, TemplateEntry being a helper class to store template entries.</p>
<p>This is all very nice but we have a problem when having multiple versions of the same bundle that hold multiple copies of the same template, this means they will stack and we have no way to access a particular version of a template. To solve this problem we store each template in three different stacks by three different URLs:</p>
<ul>
<li>&#8216;path/file.ftl&#8217;</li>
<li>&#8216;bundle://bundlename/path/file.ftl&#8217;</li>
<li>&#8216;bundle://bundlename:version/path/file.ftl&#8217;</li>
</ul>
<p>In this manner we can use the more generic URL in most cases but still can access specific versions when needed. It is important to think about the dynamic nature of OSGi as well as the possibility of several versions of the same bundle coexisting peacefully in the same environment.</p>
<p>From the perspective of any bundle using the service in the simplest case it only needs to look for a service named &#8216;freemarker.template.Configuration&#8217;. For convenience, the property &#8216;dynamicConfiguration&#8217; is set to &#8216;true&#8217; to coexist peacefully with other Configuration services (maybe coming from an official Freemarker bundle). For instance, if we know for sure our dynamic Configuration service is the only one present we can do:</p>
<pre name="code" class="java">
context.getServiceReference(Configuration.class.getName());
</pre>
<p>That will give us the highest ranking Configuration service. If there are several such services we can use a call like this to get the one that has the dynamic OSGi loader:</p>
<pre name="code" class="java">
context.getServiceReferences(Configuration.class.getName(), "dynamicConfiguration=true");
</pre>
<p>There is one last feature which lets bundle users feed an already configured template configuration object to the bundle by publishing a Configuration service with property &#8216;preparedConfiguration&#8217; set to &#8216;true&#8217;. This will get picked up by the bundle and its template loader put in sequence with the dynamic OSGi template loader. This means that any original Configuration settings are maintained (<i>For further information on service filtering based on properties please check the <a href="http://www.osgi.org/javadoc/r4v42/org/osgi/framework/BundleContext.html">BundleContext</a> javadoc.</i>).</p>
<p>Best thing to do is to go and try it by downloading the bundles <a href="http://dani.calidos.com/img/2010/osgi-08/freemarker-bundles-bin.zip">here</a>. Source is also <a href="http://dani.calidos.com/img/2010/osgi-08/osgi-template-source.tar.gz">available</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://dani.calidos.com/2010/08/11/templating-the-osgi-way-with-freemarker/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Little Big Planet 2!</title>
		<link>http://dani.calidos.com/2010/06/16/little-big-planet-2-a-la-e3/</link>
		<comments>http://dani.calidos.com/2010/06/16/little-big-planet-2-a-la-e3/#comments</comments>
		<pubDate>Wed, 16 Jun 2010 19:29:41 +0000</pubDate>
		<dc:creator>dani</dc:creator>
				<category><![CDATA[Catalan]]></category>
		<category><![CDATA[Entertainment]]></category>
		<category><![CDATA[games]]></category>
		<category><![CDATA[ps3]]></category>

		<guid isPermaLink="false">http://dani.calidos.com/?p=276</guid>
		<description><![CDATA[Els de Media Molecule, com sempre arrasant desde Guilford, UK. Demos impresionants en la roda de premsa de presentació del &#8216;Little Big Planet 2&#8242; durant l&#8217;E3. Els resultats són ben bé espectaculars, com podeu veure. PS: la web oficial de &#8230; <a href="http://dani.calidos.com/2010/06/16/little-big-planet-2-a-la-e3/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Els de <a href="http://www.mediamolecule.com/">Media Molecule</a>, com sempre arrasant desde Guilford, UK.</p>
<p><img alt="Little Big Planet 2 logo" src="http://dani.calidos.com/img/2010/littlebigplanet2.png" title="Little Big Planet 2" class="alignright" width="285" height="162" /></p>
<p>Demos impresionants en la roda de premsa de presentació del &#8216;Little Big Planet 2&#8242; durant l&#8217;<a href="http://www.e3expo.com/">E3</a>.</p>
<p>Els resultats són ben bé espectaculars, com podeu <a href="http://uk.ps3.ign.com/dor/objects/19675/littlebigplanet-2/videos/e310_lbp2_demo_061510.html;jsessionid=7lgg8e44kggl5?show=hi">veure</a>.</p>
<p>PS: la web oficial de Media Molecule és un exemple molt bo d&#8217;una web corporativa genial que no es pren seriosament a sí mateixa.</p>
]]></content:encoded>
			<wfw:commentRss>http://dani.calidos.com/2010/06/16/little-big-planet-2-a-la-e3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Components on the server (6): adding Integration Testing</title>
		<link>http://dani.calidos.com/2010/05/07/components-on-the-server-6-adding-integration-testing/</link>
		<comments>http://dani.calidos.com/2010/05/07/components-on-the-server-6-adding-integration-testing/#comments</comments>
		<pubDate>Fri, 07 May 2010 19:59:48 +0000</pubDate>
		<dc:creator>dani</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Equinox]]></category>
		<category><![CDATA[integration testing]]></category>
		<category><![CDATA[osgi]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://dani.calidos.com/?p=265</guid>
		<description><![CDATA[In this installment of the server-side OSGi series, we add integration testing capabilities to our project. Integration testing goes beyond plain unit testing and checks the interactions between real components. This is in contrast with unit testing, which generally uses &#8230; <a href="http://dani.calidos.com/2010/05/07/components-on-the-server-6-adding-integration-testing/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In this installment of the server-side OSGi series, we add integration testing capabilities to our project. Integration testing goes beyond plain unit testing and checks the interactions between real components. This is in contrast with unit testing, which generally uses mockups to represent components outside the one being tested. Please take a look at previous installments, as usual.</p>
<p>In the case of integration testing, it is manly used in a pre-production environment, with a valid build that has all unit tests passed. It can even be used in production to just after a deployment is made, taking care not to have destructive checks or massive load tests in the integration test code. YMMV.</p>
<p>To achieve integration testing we need to check the various OSGi components deployed interact in the way that is expected of them. Therefore we need to test the components in a group and not in isolation. To do that in the OSGi world means we need to have access to the OSGi context from within the tests to access services, call them and check their responses, etc.</p>
<p>To allow for this kind of integration testing within the OSGi environment, we make a slight modification to the excellent test.extender we have already patched in the previous installment.</p>
<p>Basically, the basic test.extender seeks out any JUnit test classes within the fragment bundle, creates an instance using an empty constructor and then fires up the tests. This is activated either by default when the fragment is loaded or by using &#8216;test <bundleid>&#8216; in the console. For further information please see the <a href="http://dani.calidos.com/2010/01/04/components-on-the-server-5-better-unit-testing/">previous post</a> about this subject.</p>
<p>For our integration testing, we add an extra command to test.extender:</p>
<pre class="java:nocontrols:nogutter">
public Object _integrationTest(CommandInterpreter intp) {
        String nextArgument = intp.nextArgument();
    	testExtender.integrationTest(Long.parseLong(nextArgument));
    	return null;
}
</pre>
<p>And we refactor the TestExtender to add the integrationTest method which reuses some of the code to instantiate test cases using a constructor that accepts the OSGi context as a parameter.</p>
<pre class="java:nocontrols:nogutter">
Constructor<?>[] constructors = clazz.getConstructors();
boolean foundConstructor = false;
for (int i = 0; i < constructors.length &#038;&#038; !foundConstructor; i++) {
	Constructor<?> constructor = constructors[i];
	Class<?>[] types = constructor.getParameterTypes();
	if (types.length==1 &#038;&#038; types[0].isInstance(context)) {
		foundConstructor = true;
		EClassUtils.testClass(inspectClass, constructor.newInstance(context));
	}
} // for
</pre>
<p>The OSGi context is passed onto the constructor and then the test class is run. It is obviously up to the test class to use the context appropriately for its integration testing.</p>
<p>In our cache project setup, we can do some useful integration testing on the cache.controller component, basically checking if the interaction with the provider components is behaving as we expect it. The integration testing is also added to a fragment that can be deployed optionally, of course.</p>
<p>We start by creating the fragment and adding a testing class like this:</p>
<p><img alt="Adding test class" src="http://dani.calidos.com/img/2010/osgi-06/junit-test-case.png" title="Adding test class" class="alignnone" width="472" height="540" /></p>
<p>Next, we add the constructor that accepts an OSGi context, which is very simple:</p>
<pre class="java:nocontrols:nogutter">
public CacheIntegrationTest(BundleContext ctx) {
	super();
	this.context = ctx;
}
</pre>
<p>In the setup and teardown methods we get and unget the cache service to perform the testing:</p>
<pre class="java:nocontrols:nogutter">

public void setUp() throws Exception {
	serviceReference = context.getServiceReference(Cache.class.getName());
	controller = (CacheControllerCore) context.getService(serviceReference);

}

public void tearDown() throws Exception {
	context.ungetService(serviceReference);
	controller = null;
}
</pre>
<p>In this case we get the controller cache service and store it in an instance used to perform the tests. This is quite simple and fulfills our intended purpose but we still have the flexibility to make more complex integration testing if needed.</p>
<p>Next we create as many test cases as needed:</p>
<pre class="java:nocontrols:nogutter">
public void testGet() {
	try {
		controller.init();
		double v = Math.random();
		String k = "/k"+v;
		controller.set(k, v);
		assertEquals(v, controller.get(k));
	} catch (CacheProviderException e) {
		e.printStackTrace();
		fail(e.getMessage());
	}

}
</pre>
<p>It should be noted that while the code looks like regular testing code, it is actually using real services from the OSGi environment as opposed to mockups. This means we are testing the real integration between components as well as the individual controller component code. The disadvantage here is that if there is an error in the controller we might mistake the problem with an issue with the services used. In conclusion, having integration code doesn&#8217;t negate the need to have unit tests.</p>
<p>Once we load the fragment onto the environment, first we need to obtain the bundle id of the integration fragment and then launch the integration testing in this manner:</p>
<p><code><br />
osgi> integrate 125<br />
Bundle : [125] : com.calidos.dani.osgi.cache.controller.integration<br />
_<br />
CLASS : [com.calidos.dani.osgi.cache.controller.CacheIntegrationTest]<br />
___________________________________________________________________________<br />
Method : [ testInit ] PASS<br />
Method : [ testInitInt ] PASS<br />
Method : [ testSize ] PASS<br />
14:21:43,077 WARN  CacheControllerCore Couldn't clear some of the provider caches as operation is unsupported<br />
14:21:43,077 WARN  CacheControllerCore Couldn't clear some of the provider caches as operation is unsupported<br />
Method : [ testClear ] PASS<br />
Method : [ testSet ] PASS<br />
Method : [ testGet ] PASS<br />
Method : [ testGetStatus ] PASS<br />
___________________________________________________________________________<br />
</code></p>
<p>The results tell us that all operations are OK but we need to bear in mind that the clear operation is not supported in some backend caches. If this is what is expected by the operator then all is fine.</p>
<p>We take advantage of the new integration testing functionality to make some extensive changes to logging and exception handling of the controller code. By running the integration tests we make sure all seems to work fine  (even though we still need some proper unit testing of the controller). Modifications are made quite quickly thanks to the integration tests.</p>
<p>To recap, we&#8217;ve added integration testing support to the existing &#8216;test.extender&#8217; bundle and created integration testing code for the cache controller component. This has allowed us to make code changes quickly with less risk of mistakes.</p>
<p><a href="http://dani.calidos.com/img/2010/osgi-06/test-extender-patch.txt">Here</a> you can find a patch for the test extender project as well as the patched <a href="http://dani.calidos.com/img/2010/osgi-06/test.extender-1.0-SNAPSHOT.jar">testing bundle</a> already compiled. Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://dani.calidos.com/2010/05/07/components-on-the-server-6-adding-integration-testing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>El manifest &#8211; Unlink your feeds</title>
		<link>http://dani.calidos.com/2010/05/01/el-manifest-unlink-your-feeds/</link>
		<comments>http://dani.calidos.com/2010/05/01/el-manifest-unlink-your-feeds/#comments</comments>
		<pubDate>Sat, 01 May 2010 11:48:54 +0000</pubDate>
		<dc:creator>dani</dc:creator>
				<category><![CDATA[Catalan]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[microblogging]]></category>
		<category><![CDATA[social network]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://dani.calidos.com/?p=263</guid>
		<description><![CDATA[Gràcies al Roger per enllaçar al manifest &#8216;Unlink your feeds&#8216;, em subscric totalment a la iniciativa. La idea és anar amb molt de compte en enllaçar els posts i updates de microblogging entre els diferents serveis, no sempre és lo &#8230; <a href="http://dani.calidos.com/2010/05/01/el-manifest-unlink-your-feeds/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Gràcies al <a href="http://www.ambcompte.net/general/internet/unlink-your-feeds-no-diguis-el-mateix-a-facebook-twitter-buzz/">Roger</a> per enllaçar al manifest &#8216;<a href="http://unlinkyourfeeds.tumblr.com/post/387644253/a-manifesto">Unlink your feeds</a>&#8216;, em subscric totalment a la iniciativa.</p>
<p>La idea és anar amb molt de compte en enllaçar els posts i updates de microblogging entre els diferents serveis, no sempre és lo òptim. Com diu el mateix Roger:</p>
<blockquote><p>
Un clam al cel perquè la gent deixi de reaprofitar el mateix missatge per a totes les xarxes socials. Crea soroll innecesari, molts cops perd context (hashtags a facebook, etc…) i molesta. Ok a que em diguis “avui he dinat molt bé”, però no necessito rebre-ho per triplicat.
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://dani.calidos.com/2010/05/01/el-manifest-unlink-your-feeds/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flash on iPhone OS: two extra reality checks</title>
		<link>http://dani.calidos.com/2010/04/13/flash-on-iphone-os-two-extra-reality-checks/</link>
		<comments>http://dani.calidos.com/2010/04/13/flash-on-iphone-os-two-extra-reality-checks/#comments</comments>
		<pubDate>Tue, 13 Apr 2010 19:09:25 +0000</pubDate>
		<dc:creator>dani</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Digital Video]]></category>
		<category><![CDATA[Management]]></category>
		<category><![CDATA[Media]]></category>
		<category><![CDATA[adobe]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[daring fireball]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[flash is dead]]></category>
		<category><![CDATA[ipad]]></category>
		<category><![CDATA[iphone]]></category>

		<guid isPermaLink="false">http://dani.calidos.com/?p=247</guid>
		<description><![CDATA[Unless you live in a remote and far away place you will have heard of the media impact of Apple&#8217;s decision to ban the Adobe Flash to iPhone solution and the various discussions that have ensued. I won&#8217;t bother with &#8230; <a href="http://dani.calidos.com/2010/04/13/flash-on-iphone-os-two-extra-reality-checks/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Unless you live in a remote and far away place you will have heard of the media impact of Apple&#8217;s decision to ban the <a href="http://www.loopinsight.com/2010/04/11/adobe-unveils-creative-suite-5/">Adobe Flash to iPhone</a> solution and the various <a href="http://daringfireball.net/linked/2010/04/10/lynch">discussions</a> that have <a href="http://www.devwhy.com/blog/2010/4/12/its-all-about-the-framework.html">ensued</a>. I won&#8217;t bother with providing <a href="http://www.macworld.com/article/150529/2010/04/macalope_flash.html">more links</a>. I love John Gruber&#8217;s take and Louis Gerbarg&#8217;s as well.</p>
<p>Both J.G. and L.G. have brought up many valid points: Adobe dragged their heels on Flash for mobile for a looooong time. There have been countless detabes and blog posts.</p>
<p>I&#8217;ll bring two further arguments, one logical and one historical, the latter being one that I believe hasn&#8217;t been brought up yet. </p>
<p><b>Logical argument: the fallacy of Flash being cross-platform</b></p>
<p> Moreover, why should we choose to lock ourselves onto Adobe&#8217;s propietary API instead of Apple&#8217;s propietary API? Why is Adobe&#8217;s API, specs and runtime superior to any others? Many would say the main reason (the only?) is that it&#8217;s <i>crossplatform</i>?</p>
<p>Wikipedia says that <a href="http://en.wikipedia.org/wiki/Crossplatform">cross-platform</a> means: </p>
<blockquote><p>&#8220;an attribute conferred to computer software or computing methods and concepts that are implemented and inter-operate on multiple computer platforms&#8221;.</p></blockquote>
<p>Oh, okay, so multiple means Windows, Mac and Linux <b>desktops</b>. Hello?!? Anyone there?!? This is 2010 and the 90&#8242;s called because they want their meaning of &#8220;platform&#8221; back. Nowadays, <i>multiple</i> means desktop <b>and</b> mobile. Therefore:</p>
<ul>
<li>Flash Lite is a joke. Where are the multiplicity of mobile devices supporting proper Flash 10.1 today? </li>
<li>Where is the pervasive <a href="http://androinica.com/2010/02/25/flash-10-1-will-not-be-supported-on-all-android-phones/">Android support</a> today? HTC Hero buyers are screwed, a phone bought as little as less than a year ago won&#8217;t be supported.</li>
<li>Where is the support for Windows Mobile devices? <a href="http://www.coated.com/no-adobe-flash-support-on-windows-mobile-6-5/">Not there until WinMo7</a>. You mean it will be supported on a OS that it&#8217;s not even there yet?</li>
</ul>
<p>Well, you could say that the Open Screen Project and the releasing of the FLV, SWF and the lot specs are true multiplatformness&#8230; Well, so far so good but where is the real market traction? Where are the tried-and-true implementations? Adobe has released this technology but until it gains traction it&#8217;s no more than a glorified press release. Apple can play this game too, with tech such as <a href="http://webkit.org/">WebKit</a> which is <a href="http://en.wikipedia.org/wiki/WebKit">used</a> in a zillion <a href="http://blogs.zdnet.com/Apple/?p=2208">places</a> including Adobe&#8217;s own Air platform. Press releases and freeing technologies are irrelevant until <i>adopted</i>. A good initiative which I applaud, but still not widely used.</p>
<p>No, Flash is not cross-platform anymore. What is the marketshare of the mobile devices capable of running Flash 10.1? Nowhere big enough for Adobe to be pulling muscle and demanding anything. It seems Adobe is using Flash devs and aficionados as cannon fodder or -as Gerbarg more aptly puts it-, &#8220;Adobe used its userbase and their livelihood as a bargaining chip&#8221;. Adobe dragged its feet for years in the mobile arena and now is paying for its mistakes.</p>
<p><b>Historical argument: <del datetime="2010-04-12T19:19:12+00:00">Macromedia</del> Adobe has screwed its own developers like this before</b></p>
<p>In the nineties Macromedia had a great product already. It was cross-platform (as per 90&#8242;s definition), had powerful scripting capabilities, an powerful extension architecture, a great browser plug-in runtime that was also cross-platform, video capabilities, awesome rapid development tools, stellar graphics integration, built-in debugger, great performance, etc. It was called Director and it was really cool.</p>
<p>Then Macromedia bought FutureSplash in 1996 which would be later renamed to Flash. It had far less capabilities that Director at the time (no real scripting at the beginning, etc.) and would remain technically inferior for sometime, having no debugging and many other features being missing for a long while. However, it had three distinct advantages. Strike one: having less features and being a newer codebase meant it could have a more lightweight runtime than the Director one. Strike two: it had support for vector graphics, which desktop CPUs at the time were just capable of displaying and animating adequately. Director came from a less CPU-intensive bitmap background, faster but consuming more space than vector definitions and looking less sleek in many cases.</p>
<p>One &#8220;advantage&#8221; remained. So what did Macromedia do? Take advantage of the FutureSplash technology acquisition and the Director established developer base? It could have easily added the vector drawing technology into Director (it supported many types of media already). Refactoring the code and runtime would be no trivial feat but doable. Any Director developer would have been OK with a new restriction being put into place that meant only vector-graphics resources being allowed any new Director web runtime, would have welcomed and embraced such a change.</p>
<p>Strike three: Macromedia realised that with the maturity and feature-complete of Director no long-winded upgrade path was in sight. Just adding vector graphics and a streamlined runtime would do for one or two Director upgrades, no more. They thoroughly screwed the existing loyal developer base royally and released a sleek new 1.0 Flash product. Then they spent years releasing upgrades that added features that had already been present in Director for some time. They created another cash cow, a cow that would ride the wave of the Web explosion of the .com era. Director out. And no, I&#8217;m not buying any of the &#8220;official&#8221; reasons for its languishing and Flash emergence. It was all about <i>money</i>.</p>
<p>I am not crying for Director&#8217;s demise -or rather, being put into life-support mode. It was a good platform and many (myself included) made good money using it. This doesn&#8217;t mean Adobe didn&#8217;t screw up many of its own developers and went in for the next cash cow.</p>
<p>I am not buying Flash developers and supporters taking offense and the moral high ground, the company (now Adobe) you support has done a much worse thing to its <i>own developers</i>. Why should Apple even care for developers of other platforms? Just because you learned a framework and are scared of it fading away doesn&#8217;t mean anything&#8230; Some of us have done this many times before and moved on&#8230;</p>
<p><b>Final word: put your code where your mouth is</b></p>
<p>Okay. Time to recap, folks. If Flash is such a great platform -it&#8217;s actually not bad but not that good either- go ahead and develop these killer apps on Android or WinMo7 whenever that comes out. With killer apps being available on competing platforms making a huge difference Apple will simply change the clause and allow you in. They&#8217;re not stupid. </p>
<p/>
Now stop crying and start coding. Myself, will try to put this out of my mind.</p>
]]></content:encoded>
			<wfw:commentRss>http://dani.calidos.com/2010/04/13/flash-on-iphone-os-two-extra-reality-checks/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

