<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">

<channel>
	<title>Tus ceros y mis unos</title>
	
	<link>http://mikiorbe.wordpress.com</link>
	<description>Blog de Miguel Orbegozo. Desarrollo entretenido</description>
	<lastBuildDate>Fri, 23 Oct 2009 06:51:41 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>es</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain="mikiorbe.wordpress.com" port="80" path="/?rsscloud=notify" registerProcedure="" protocol="http-post" />
<image>
		<url>http://www.gravatar.com/blavatar/3b96510774fe4519b214cf863da0d429?s=96&amp;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>Tus ceros y mis unos</title>
		<link>http://mikiorbe.wordpress.com</link>
	</image>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/TusCerosYMisUnos" type="application/rss+xml" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">TusCerosYMisUnos</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>JUnit: Herramienta indispensable para el desarrollo Java</title>
		<link>http://mikiorbe.wordpress.com/2009/10/23/junit-herramienta-indispensable-para-el-desarrollo-java/</link>
		<comments>http://mikiorbe.wordpress.com/2009/10/23/junit-herramienta-indispensable-para-el-desarrollo-java/#comments</comments>
		<pubDate>Fri, 23 Oct 2009 06:51:41 +0000</pubDate>
		<dc:creator>Miguel</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JUnit]]></category>

		<guid isPermaLink="false">http://mikiorbe.wordpress.com/?p=589</guid>
		<description><![CDATA[Hoy voy a hablar de una herramienta que debería ser de uso común para el desarrollo. Estoy hablando de JUnit, la librería de pruebas unitarias más utilizado en entornos Java.
Las pruebas unitarias consisten en desarrollar código para probar una determinada funcionalidad de nuestra aplicación.
Vamos a ver un pequeño ejemplo. Supongamos que estamos haciendo una librería [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikiorbe.wordpress.com&blog=3806599&post=589&subd=mikiorbe&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Hoy voy a hablar de una herramienta que debería ser de uso común para el desarrollo. Estoy hablando de <a title="JUnit" href="http://www.junit.org/">JUnit</a>, la librería de pruebas unitarias más utilizado en entornos Java.</p>
<p>Las <a title="Pruebas unitarias en Wikipedia ES" href="http://es.wikipedia.org/wiki/Prueba_unitaria">pruebas unitarias</a> consisten en desarrollar código para probar una determinada funcionalidad de nuestra aplicación.</p>
<p>Vamos a ver un pequeño ejemplo. Supongamos que estamos haciendo una librería matemática que incluye una funcion para calcular el <a title="Factorial en Wikipedia ES" href="http://es.wikipedia.org/wiki/Factorial">factorial</a> de un número. Podría ser una clase parecida a la siguiente:</p>
<pre class="brush: java;">
package org.tcymu.util;

public class MathLibrary {
	public static int factorial(int n) throws IllegalArgumentException {
		int response = 1;

		if (n &lt; 0) {
			throw new IllegalArgumentException();
		}

		if (n &gt; 0) {
			response = n * factorial(n - 1);
		}

		return response;
	}
}
</pre>
<p>En esta entrada voy a utilizar las facilidades que da <a title="Eclipse" href="http://www.eclipse.org/">Eclipse</a> gracias a su integración con JUnit. Para ello en la vista <em>package</em> sobre la clase que queremos probar hacemos botón dereco -&gt; &#8220;New&#8221; -&gt; &#8220;JUnit Test Case&#8221;.</p>
<p style="text-align:center;"><a href="http://mikiorbe.files.wordpress.com/2009/10/junit_1_320x220.png"><img class="size-full wp-image-592 aligncenter" title="junit_1_320x220" src="http://mikiorbe.files.wordpress.com/2009/10/junit_1_320x220.png?w=320&#038;h=220" alt="Nuevo Test JUnit" width="320" height="220" /></a></p>
<p>Nos aparece la siguiente ventana en la que seleccionamos &#8220;New JUnit 4 test&#8221; (tened en cuenta que JUnit 4 necesita Java 1.5 o superior).</p>
<p><a href="http://mikiorbe.files.wordpress.com/2009/10/junit_2_320x360.png"><img class="aligncenter size-full wp-image-595" title="junit_2_320x360" src="http://mikiorbe.files.wordpress.com/2009/10/junit_2_320x360.png?w=320&#038;h=360" alt="junit_2_320x360" width="320" height="360" /></a></p>
<p>Podemos ver que nos propone un nombre para la clase de pruebas, así como un paquete y una carpeta de fuentes (por defecto propone el mismo paquete que las fuentes, aunque podríamos elegir otro). También podemos seleccionar que nos cree los siguientes métodos de apoyo para preparar el entorno de los test o liberar recursos:</p>
<p>- Métodos <code>setUp</code> y <code>tearDown</code>. Los ejecuta antes de llamar a cada método de prueba en esa clase. La secuencia sería <code>setUp</code>, <code>metodo1Test</code>, <code>tearDown</code>, <code>setUp</code>, <code>metodo2Test</code>, <code>tearDown</code>.</p>
<p>- Métodos <code>setUpBeforeClass</code> y <code>tearDownAfterClass</code>. Estos métodos se ejecutan antes y después de todos los métodos de la clase. La secuencia sería <code>setUpBeforeClass</code>, <code>metodo1Test</code>, <code>metodo2Test</code>, <code>tearDownAfterClass</code>.</p>
<p>A continuación nos pide los métodos que queremos probar. En este ejemplo seleccionamos el método que queremos probar (<code>factorial</code>) y ninguno de los métodos de apoyo (en nuestro sencillo ejemplo no necesitamos crear ni liberar nada).</p>
<p><a href="http://mikiorbe.files.wordpress.com/2009/10/junit_3_320x360.png"><img class="aligncenter size-full wp-image-596" title="junit_3_320x360" src="http://mikiorbe.files.wordpress.com/2009/10/junit_3_320x360.png?w=320&#038;h=360" alt="junit_3_320x360" width="320" height="360" /></a></p>
<p>Tras finalizar y si no tenemos la librería JUnit 4 en el <em>Build Path</em> nos la añade. Y por último crea el esqueleto de la clase de prueba:</p>
<pre class="brush: java;">
package org.tcymu.util;

import static org.junit.Assert.*;

import org.junit.Test;

public class MathLibraryTest {

	@Test
	public void testFactorial() {
		fail(&quot;Not yet implemented&quot;);
	}

}
</pre>
<p>Hay que destacar que lo que realmente convierte al método en un test que ejecutará JUnit es la <a title="Anotaciones Java en Wikipedia ES" href="http://es.wikipedia.org/wiki/Anotaci%C3%B3n_Java">anotación Java</a> <code>@Test</code>, al igual que lo que marcaría a los métodos de apoyo serían anotaciones como <code>@BeforeClass</code>, <code>@AfterClass</code>, <code>@Before</code> y <code>@After</code>.</p>
<p>Podemos observar que el método <code>testFactorial</code> sólo contiene la línea <code>fail("Not yet implemented");</code> , por lo que si ejecutamos el test (mediante botón derecho sobre la clase de pruebas y &#8220;Run As&#8221; -&gt; &#8220;JUnit Test&#8221; se nos abre la vista de JUnit con el siguiente resultado:</p>
<p><a href="http://mikiorbe.files.wordpress.com/2009/10/junit_4.png"><img class="aligncenter size-full wp-image-597" title="junit_4" src="http://mikiorbe.files.wordpress.com/2009/10/junit_4.png?w=286&#038;h=240" alt="junit_4" width="286" height="240" /></a></p>
<p>Por tanto es hora de implementar nuestra prueba para pasar la barra al ansiado color verde. Básicamente se hacen comprobaciones de los resultados esperados frente a los recibidos mediante la clase <code>org.junit.Assert</code> (<a title="Documentación Javadoc de JUnit" href="http://junit.org/junit/javadoc/4.5/">documentación Javadoc de JUnit</a>).</p>
<pre class="brush: java;">
package org.tcymu.util;

import static org.junit.Assert.*;

import org.junit.Assert;
import org.junit.Test;

public class MathLibraryTest {

	@Test
	public void testFactorial() {
		Assert.assertEquals(1, MathLibrary.factorial(0));
		Assert.assertTrue(1 == MathLibrary.factorial(1));
		Assert.assertEquals(24, MathLibrary.factorial(4));
		Assert.assertEquals(720, MathLibrary.factorial(6));

		boolean excepcionLanzada = false;
		try {
			MathLibrary.factorial(-1);
		} catch (IllegalArgumentException e) {
			excepcionLanzada = true;
		}
		Assert.assertTrue(excepcionLanzada);
	}

}
</pre>
<p>Vemos que utilizamos varios métodos para comprobar que se obtiene el resultado esperado. También podemos ver cómo probamos que se lanza la excepción esperada cuando el argumento no es válido (creo haber leído en algún sitio que se iba a mejorar la prueba de excepciones en próximas versiones, pero no consigo localizar la noticia).</p>
<p>Una vez que se ejecutan la prueba con éxito (la barrita verde) sabemos que el método funciona como nosotros esperamos. Ahora tras cualquier cambio en el código volveríamos a ejecutar JUnit para comprobar que no hemos roto nada. Esto nos da una gran seguridad a la hora de meter mano o <a title="Refactorización en Wikipedia ES" href="http://es.wikipedia.org/wiki/Refactorizar">refactorizar</a> métodos complejos.</p>
<p>Por último no quisiera terminar la entrada sin nombrar un par de temas relacionados con las pruebas unitarias.</p>
<p>- Una buena prueba debe ser repetible (se debe de poder lanzar cuantas veces queramos sin afectar a nada). Por ello cada vez más se automatizan las pruebas en los procesos de integración continua de forma que antes de generarse una versión de una aplicación se corren todas las pruebas para dicha aplicación.</p>
<p>- Existe un modelo de desarrollo que promueve que primero se escriban las pruebas y después el código. Es el llamado <a title="Desarrollo guiado por pruebas en Wikipedia ES" href="http://es.wikipedia.org/wiki/Desarrollo_guiado_por_pruebas">Desarrollo Guiado por Pruebas</a> o Test Driven Development (TDD).</p>
<p>Espero que os haya gustado esta pequeña introducción.</p>
 Tagged: Java, JUnit <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mikiorbe.wordpress.com/589/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mikiorbe.wordpress.com/589/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mikiorbe.wordpress.com/589/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mikiorbe.wordpress.com/589/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mikiorbe.wordpress.com/589/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mikiorbe.wordpress.com/589/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mikiorbe.wordpress.com/589/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mikiorbe.wordpress.com/589/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mikiorbe.wordpress.com/589/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mikiorbe.wordpress.com/589/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikiorbe.wordpress.com&blog=3806599&post=589&subd=mikiorbe&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://mikiorbe.wordpress.com/2009/10/23/junit-herramienta-indispensable-para-el-desarrollo-java/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e0aa1c86de99e8f09a34f5849f358bcc?s=96&amp;d=identicon&amp;r=G" medium="image">
			<media:title type="html">mikiorbe</media:title>
		</media:content>

		<media:content url="http://mikiorbe.files.wordpress.com/2009/10/junit_1_320x220.png" medium="image">
			<media:title type="html">junit_1_320x220</media:title>
		</media:content>

		<media:content url="http://mikiorbe.files.wordpress.com/2009/10/junit_2_320x360.png" medium="image">
			<media:title type="html">junit_2_320x360</media:title>
		</media:content>

		<media:content url="http://mikiorbe.files.wordpress.com/2009/10/junit_3_320x360.png" medium="image">
			<media:title type="html">junit_3_320x360</media:title>
		</media:content>

		<media:content url="http://mikiorbe.files.wordpress.com/2009/10/junit_4.png" medium="image">
			<media:title type="html">junit_4</media:title>
		</media:content>
	</item>
		<item>
		<title>Pequeña introducción a Git</title>
		<link>http://mikiorbe.wordpress.com/2009/09/03/pequena-introduccion-a-git/</link>
		<comments>http://mikiorbe.wordpress.com/2009/09/03/pequena-introduccion-a-git/#comments</comments>
		<pubDate>Thu, 03 Sep 2009 18:10:18 +0000</pubDate>
		<dc:creator>Miguel</dc:creator>
				<category><![CDATA[Entorno Desarrollo]]></category>
		<category><![CDATA[CVS]]></category>
		<category><![CDATA[Git]]></category>

		<guid isPermaLink="false">http://mikiorbe.wordpress.com/?p=583</guid>
		<description><![CDATA[Git es un sistema de control de versiones al igual que CVS, Subversion y otros.
Git fue diseñado por Linus Torwalds (creador de Linux) para utilizarlo en el desarrollo del núcleo de Linux. En su sección de descargas podemos encontrar entre otras, enlaces a versiones para Linux (en rpm o deb), MacOS y Windows (a través [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikiorbe.wordpress.com&blog=3806599&post=583&subd=mikiorbe&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a title="Git" href="http://git-scm.com/">Git</a> es un sistema de control de versiones al igual que <a title="CVS" href="http://www.nongnu.org/cvs/">CVS</a>, <a title="Subversion" href="http://subversion.tigris.org/">Subversion</a> y otros.</p>
<p>Git fue diseñado por <a title="Linus Torwalds en Wikipedia ES" href="http://es.wikipedia.org/wiki/Linus_Torvalds">Linus Torwalds</a> (creador de Linux) para utilizarlo en el desarrollo del núcleo de Linux. En su sección de descargas podemos encontrar entre otras, enlaces a versiones para Linux (en rpm o deb), MacOS y Windows (a través de <a title="Cygwin" href="http://www.cygwin.com/">Cygwin</a> o del proyecto <a title="MSysGit" href="http://code.google.com/p/msysgit/">MSysGit</a> que provee instalables completos e incluso una versión portable).</p>
<p>Si venimos desde un enfoque más clásico como CVS o Subversion, la principal diferencia que aporta Git es que es un sistema distribuido. ¿Y qué quiere decir distribuido?. Pues que a diferencia de CVS o Subversion podemos trabajar con nuestro control de versiones aunque no estemos conectados a una red, ya que es como si tuviésemos el servidor en nuestra propia máquina. De esta forma está diferenciado lo que son las acciones con nuestro repositorio y las que llevamos cabo con repositorios remotos (ese sería el estilo CVS).</p>
<p><img class="aligncenter size-full wp-image-585" title="git_1" src="http://mikiorbe.files.wordpress.com/2009/09/git_1.png?w=455&#038;h=134" alt="git_1" width="455" height="134" /></p>
<p>En principio es una solución muy recomendable si queremos mantener un versionado en nuestra máquina de desarrollo (en este caso sólo utilizaremos los comandos entre desarrollo y el repositorio propio del esquema. Vamos a ver un pequeño resumen de los comandos que utilizaríamos en este caso.</p>
<ul>
<li>Lo primero que necesitamos es configurar nuestro usuario:
<p><code>git config --global user.name "Don Nadie"<br />
git config --global user.email "don.nadie@test.com"</code>
</li>
<li>Para crear un repositorio nos situaremos en el directorio principal de nuestro proyecto (o en uno vacío si es un proyecto nuevo) y haremos:
<p><code>git init</code></p>
<p>y si el proyecto está empezado añadiremos los archivos mediante</p>
<p><code>git add .</code><br />
<code>git commit -m "Mensaje"</code> (Si no se le pasa -m nos pedirá un mensaje, ya que es obligatorio)</p>
<p>con lo que ya tendremos todo nuestro proyecto bajo el control de versiones.
</li>
<li>Para el ciclo de desarrollo normal, primero se añaden los cambios al índice (es como un almacén intermedio que almacena todos los cambios) y luego lo persistiremos en el repositorio.
<p><code>git add ruta/fichero</code> Añade el fichero nuevo o modificado al índice<br />
<code>git commit</code> Persiste los cambios que tenemos en el índice al repositorio (nos pide mensaje)<br />
<code>git commit -a</code> Hace el paso al índice y el commit en un solo paso
</li>
<li>Para ver el estado del desarrollo podemos utilizar los siguientes comandos:
<p><code>git status</code> Muestra el estado de la rama de desarrollo<br />
<code>git diff</code> Muestra las diferencias entre la rama de desarrollo y el índice<br />
<code>git diff --cached</code> Muestra las diferencias entre el índice y el HEAD (último commit)<br />
<code>git diff HEAD</code> Muestra las diferencias entre la rama de desarrollo y el HEAD<br />
<code>git log</code> Nos muestra un historial de los commits del repositorio
</li>
<li>El trabajo con ramas es muy sencillo en Git.
<p><code>git branch test</code> Crea una rama de nombre &#8220;test&#8221; a partir de la actual<br />
<code>git branch</code> Nos muestra las ramas existentes y la rama en la que nos encontramos (cuando hacemos git status también nos muestra la rama en la que nos encontramos)<br />
<code>git checkout</code> test Nos sitúa en la rama test<br />
<code>git merge test</code> Si nos hemos situado en la rama master (la rama principal, en la que empezamos) nos combina los cambios en la rama test con esta rama
</li>
</ul>
<p>Git también tiene gran potencia para compartir el código con otros desarrolladores, aunque este caso lo dejaremos para otra entrada.</p>
<p>Por último no quisiera terminar esta entrada sin decir que Git no es el único control de versiones distribuido. También <a title="Mercurial" href="http://mercurial.selenic.com/wiki/">Mercurial</a> o <a title="Bazaar" href="http://bazaar-vcs.org/">Bazaar</a> nos pueden servir para los mismos fines e incluso pueden ser más sencillas si estamos acostumbrados a CVS.</p>
 Tagged: CVS, Git <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mikiorbe.wordpress.com/583/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mikiorbe.wordpress.com/583/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mikiorbe.wordpress.com/583/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mikiorbe.wordpress.com/583/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mikiorbe.wordpress.com/583/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mikiorbe.wordpress.com/583/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mikiorbe.wordpress.com/583/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mikiorbe.wordpress.com/583/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mikiorbe.wordpress.com/583/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mikiorbe.wordpress.com/583/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikiorbe.wordpress.com&blog=3806599&post=583&subd=mikiorbe&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://mikiorbe.wordpress.com/2009/09/03/pequena-introduccion-a-git/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e0aa1c86de99e8f09a34f5849f358bcc?s=96&amp;d=identicon&amp;r=G" medium="image">
			<media:title type="html">mikiorbe</media:title>
		</media:content>

		<media:content url="http://mikiorbe.files.wordpress.com/2009/09/git_1.png" medium="image">
			<media:title type="html">git_1</media:title>
		</media:content>
	</item>
		<item>
		<title>Estructura de directorios en Linux</title>
		<link>http://mikiorbe.wordpress.com/2009/07/24/estructura-de-directorios-en-linux/</link>
		<comments>http://mikiorbe.wordpress.com/2009/07/24/estructura-de-directorios-en-linux/#comments</comments>
		<pubDate>Fri, 24 Jul 2009 06:24:54 +0000</pubDate>
		<dc:creator>Miguel</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://mikiorbe.wordpress.com/?p=577</guid>
		<description><![CDATA[En esta entrada vamos a intentar explicar un poco la estructura de directorios en Linux, concretamente la que se define en el FHS (Filesystem Hierarchy Standar) que es un estándar definido por un grupo de organizaciones (entre ellas empresas como HP, Red Hat o IBM). Eso sí, luego cada distribución es un mundo, y los [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikiorbe.wordpress.com&blog=3806599&post=577&subd=mikiorbe&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>En esta entrada vamos a intentar explicar un poco la estructura de directorios en Linux, concretamente la que se define en el FHS (<a title="Filesystem Hierarchy Standar" href="http://www.pathname.com/fhs/">Filesystem Hierarchy Standar</a>) que es un estándar definido por un grupo de organizaciones (entre ellas empresas como HP, Red Hat o IBM). Eso sí, luego cada distribución es un mundo, y los estándares no se siguen al 100%.</p>
<p>Si listamos el contenido del directorio raiz en nuestro Linux (mediante cd / nos situamos en el raiz y con ls hacemos el listado) veremos algo similar (en este caso es mi Xubuntu a lo siguiente.</p>
<p><img class="aligncenter size-full wp-image-579" title="LinuxFHS_1" src="http://mikiorbe.files.wordpress.com/2009/07/linuxfhs_1.png?w=455&#038;h=286" alt="LinuxFHS_1" width="455" height="286" /></p>
<p>Los directorios que nos encontramos son los siguientes:</p>
<ul>
<li><strong>bin</strong>: Es el directorio en el que encontramos los principales ejecutables del sistema.</li>
<li><strong>sbin</strong>: Contiene ejecutables reservados al superusuario.</li>
<li><strong>boot</strong>: El directorio boot contiene los elementos necesarios para el arranque del sistema.</li>
<li><strong>dev</strong>: En Linux los dispositivos como particiones de discos duros, modems, terminales y demás se representan como un fichero. El directorio dev continene dichos elementos (devices en inglés).</li>
<li><strong>etc</strong>: Este directorio contiene la configuración de nuestro sistema.</li>
<li><strong>home</strong>: Dentro de este directorio se encuentran los directorios de los distintos usuarios del sistema. Es algo similar al Documents and Settings de los sistemas Windows.</li>
<li><strong>lib</strong>: En este directorio se encuentran librerías de uso común por distintas aplicaciones como los ejecutables de bin y sbin.</li>
<li><strong>media</strong>: En media se suelen montar los elementos no permanentes tales como memorias usb o cdroms. Este es un directorio de relativamente uso reciente, aunque yo las distribuciones que uso ya lo utilizan.</li>
<li><strong>mnt</strong>: Este directorio antiguamente se utilizaba para montar casi todo. Hoy en días según el FHS se debe utilizar para montajes temporales por parte del administrador.</li>
<li><strong>opt</strong>: En este directorio se debería instalar el software de terceras partes. Sería algo similar al &#8220;Archivos de Programa&#8221; o &#8220;Program Files&#8221; de Windows.</li>
<li><strong>proc</strong>: Este es un directorio virtual en el que el núcleo y otros procesos muestran su estado. Por ejemplo el archivo uptime mantiene el tiempo que lleva en funcionamiento el sistema.</li>
<li><strong>root</strong>: Es el directorio personal del superusuario.</li>
<li><strong>srv</strong>: En srv según el estandar se deberían situar los ficheros que sirve nuestro sistema (a través de un servidor web o ftp por ejemplo). Sin embargo no está demasiado difundido su uso.</li>
<li><strong>sys</strong>: Otro directorio virtual que es utilizado por los elementos conectados al sistema, como los elementos Plug and Play.</li>
<li><strong>tmp</strong>: Es el directorio de uso temporal del sistema.</li>
<li><strong>usr</strong>: Este directorio es toda una estructura de directorios estáticos (no varían) que contiene tanto software como otros recursos. Podría ser compartido entre varios sistemas.</li>
<li><strong>var</strong>: Otra gran estructura de directorios, aunque contrariamente a usr, la información que se almacena en var es variable, como por ejemplo los logs del sistema.</li>
</ul>
<p>Como podemos ver, no es una estructura sencilla ni especialmente intuitiva, por lo que no es de extrañar que algunas distribuciones como por ejemplo <a title="Gobolinux" href="http://www.gobolinux.org/index.php?lang=es_ES">Gobolinux</a> utilicen una estructura completamente diferente.</p>
 Tagged: Linux <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mikiorbe.wordpress.com/577/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mikiorbe.wordpress.com/577/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mikiorbe.wordpress.com/577/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mikiorbe.wordpress.com/577/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mikiorbe.wordpress.com/577/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mikiorbe.wordpress.com/577/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mikiorbe.wordpress.com/577/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mikiorbe.wordpress.com/577/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mikiorbe.wordpress.com/577/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mikiorbe.wordpress.com/577/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikiorbe.wordpress.com&blog=3806599&post=577&subd=mikiorbe&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://mikiorbe.wordpress.com/2009/07/24/estructura-de-directorios-en-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e0aa1c86de99e8f09a34f5849f358bcc?s=96&amp;d=identicon&amp;r=G" medium="image">
			<media:title type="html">mikiorbe</media:title>
		</media:content>

		<media:content url="http://mikiorbe.files.wordpress.com/2009/07/linuxfhs_1.png" medium="image">
			<media:title type="html">LinuxFHS_1</media:title>
		</media:content>
	</item>
		<item>
		<title>Descripción de iBatis: ¿Qué es?, ¿para qué sirve?</title>
		<link>http://mikiorbe.wordpress.com/2009/06/24/descripcion-de-ibatis-%c2%bfque-es-%c2%bfpara-que-sirve/</link>
		<comments>http://mikiorbe.wordpress.com/2009/06/24/descripcion-de-ibatis-%c2%bfque-es-%c2%bfpara-que-sirve/#comments</comments>
		<pubDate>Wed, 24 Jun 2009 21:05:35 +0000</pubDate>
		<dc:creator>Miguel</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[iBatis]]></category>
		<category><![CDATA[Persistencia]]></category>

		<guid isPermaLink="false">http://mikiorbe.wordpress.com/?p=569</guid>
		<description><![CDATA[iBatis es un framework de persistencia para Java, aunque con bastantes diferencias respecto a Hibernate, el gran dominador en este segmento.

La principal diferencia entre iBatis e Hibernate es que iBatis no es un ORM (Mapeo Objeto Relacional). Por lo tanto Hibernate genera el SQL para mapear objetos a tablas de la base de datos, mientras [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikiorbe.wordpress.com&blog=3806599&post=569&subd=mikiorbe&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a title="iBatis" href="http://ibatis.apache.org/index.html">iBatis</a> es un framework de persistencia para Java, aunque con bastantes diferencias respecto a <a title="Hibernate" href="https://www.hibernate.org/">Hibernate</a>, el gran dominador en este segmento.</p>
<p><img class="aligncenter size-full wp-image-575" title="ibatis" src="http://mikiorbe.files.wordpress.com/2009/06/ibatis.jpg?w=200&#038;h=63" alt="ibatis" width="200" height="63" /></p>
<p>La principal diferencia entre iBatis e Hibernate es que iBatis no es un <a title="ORM en Wikipedia ES" href="http://es.wikipedia.org/wiki/Mapeo_objeto-relacional">ORM</a> (Mapeo Objeto Relacional). Por lo tanto Hibernate genera el SQL para mapear objetos a tablas de la base de datos, mientras que en iBatis el SQL lo tendremos que escribir nosotros. Si tenemos un modelo de datos (nuestras tablas de BBDD) bastante diferente a nuestro modelo de negocio (nuestras clases Java) Hibernate nos puede dar bastantes dolores de cabeza.</p>
<p>Lo que sí hace iBatis es lo siguiente:</p>
<ul>
<li>Ejecuta el SQL escrito por nosotros mediante <a title="JDBC en Wikipedia ES" href="http://es.wikipedia.org/wiki/Java_Database_Connectivity">JDBC</a>[] (Java DataBase Connectivity), por lo que nos olvidamos de los múltiples try/catch.</li>
<li>Mapea propiedades de objetos a parámetros para las <a title="PreparedStatement" href="http://www.programacion.com/bbdd/tutorial/jdbc/8/">PreparedStatement</a> (sentencias SQL parametrizables).</li>
<li>Mapea los resultados de una query a un objeto o una lista de objetos.</li>
</ul>
<p>En esta entrada ahora podría poner un pequeño ejemplo de utilización de iBatis, pero eso es lo que podemos encontrar en la <a title="Documentación de iBatis en español" href="http://svn.apache.org/repos/asf/ibatis/trunk/java/ibatis-2/ibatis-2-docs/es/">documentación de iBatis en español</a>.</p>
<p>Como resumen de lo que se puede ver en dicah documentación comentar:</p>
<ul>
<li>Tendremos un fichero de configuración de iBatis (<em>SqlMapConfig.xml</em> habitualmente) en el que indicaremos algunos parámetros de iBatis (como si está activo el cacheado), el <code>DataSource</code> (soporta varios tipos de <code>DataSource</code>) y los distintos mapeos SQL.</li>
<li>Tendremos al menos un fichero de mapeo xml, en el que se indican las sentencias SQL, los parámetros a mapear o los resultados a mapear.</li>
<li>Tendremos una clase que implementa <code>SQLMapClient</code> que es el interface que contiene los métodos para realizar las sentencias SQL (<code>queryForObject</code>, <code>queryForList</code> o <code>delete</code> entre otros muchos). Esta clase la habremos obtenido mediante <code>SqlMapClientBuilder</code>.</li>
</ul>
<p>Otro punto fuerte de iBatis es su integración con <a title="Introducción a Spring" href="http://mikiorbe.wordpress.com/2008/11/20/%c2%bfque-es-spring-explicacion-basica-y-descripcion/">Spring</a>. Para trabajar con iBatis integrado en Spring los pasos a seguir serían los siguientes:</p>
<ul>
<li>El <code>DataSource</code> lo definiremos como un Bean en los archivos de definición de Spring. El resto del <em>SqlMapConfig.xml</em> y los xml de mapeo seguirían igual.</li>
<li>Spring proporciona el <code>SqlMapClientFactoryBean</code> y <code>SqlMapClientTemplate</code>. A la factoría le proporcionaremos el DataSource y al template le proporcionamos la factoría. Ese  template es la clase que nos proporciona los mismo métodos que el <code>SQLMapClient</code> visto anteriormente.</li>
</ul>
<p>También quiero nomrar en esta entrada a <a title="Ibator" href="http://ibatis.apache.org/ibator.html">Ibator</a>, que es una herramienta para generar código para iBatis. A partir de una tabla de base de datos es capaz de generar el xml de mapeo, las clases Java que representan al modelo de datos e incluso los <a title="DAO en Wikipedia ES" href="http://es.wikipedia.org/wiki/Data_Access_Object">DAO</a> (Objetos de Acceso a Datos). Viene incluido un plugin para Eclipse. Aunque no la he utilizado, puede ser una herramienta útil en ocasiones.</p>
<p>Y por último decir que aunque sólo he hablado de iBatis para Java, desde la página del proyecto nos podemos descargar versiones para .Net o Ruby.</p>
 Tagged: iBatis, Java, Persistencia <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mikiorbe.wordpress.com/569/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mikiorbe.wordpress.com/569/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mikiorbe.wordpress.com/569/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mikiorbe.wordpress.com/569/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mikiorbe.wordpress.com/569/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mikiorbe.wordpress.com/569/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mikiorbe.wordpress.com/569/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mikiorbe.wordpress.com/569/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mikiorbe.wordpress.com/569/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mikiorbe.wordpress.com/569/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikiorbe.wordpress.com&blog=3806599&post=569&subd=mikiorbe&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://mikiorbe.wordpress.com/2009/06/24/descripcion-de-ibatis-%c2%bfque-es-%c2%bfpara-que-sirve/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e0aa1c86de99e8f09a34f5849f358bcc?s=96&amp;d=identicon&amp;r=G" medium="image">
			<media:title type="html">mikiorbe</media:title>
		</media:content>

		<media:content url="http://mikiorbe.files.wordpress.com/2009/06/ibatis.jpg" medium="image">
			<media:title type="html">ibatis</media:title>
		</media:content>
	</item>
		<item>
		<title>AJAX en CakePHP mediante jQuery</title>
		<link>http://mikiorbe.wordpress.com/2009/06/01/ajax-en-cakephp-mediante-jquery/</link>
		<comments>http://mikiorbe.wordpress.com/2009/06/01/ajax-en-cakephp-mediante-jquery/#comments</comments>
		<pubDate>Mon, 01 Jun 2009 17:21:27 +0000</pubDate>
		<dc:creator>Miguel</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[JQuery]]></category>

		<guid isPermaLink="false">http://mikiorbe.wordpress.com/?p=560</guid>
		<description><![CDATA[Hace poco hemos visto cómo utilizar AJAX en un formulario con CakePHP y hemos hablado en varias ocasiones de jQuery. Ahora vamos a ver cómo utilizar jQuery a través de CakePHP.
Dean Sofer comenta en Serving up actions as AJAX with jQuery in a few simple steps ( en inglés) que él no cree necesario un [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikiorbe.wordpress.com&blog=3806599&post=560&subd=mikiorbe&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Hace poco hemos visto cómo utilizar AJAX en un formulario con <a title="Formulario AJAX en CakePHP" href="http://mikiorbe.wordpress.com/2009/05/05/formulario-ajax-en-cakephp/">CakePHP</a> y hemos hablado en varias ocasiones de <a title="jQuery en Tus Ceros y Mis Unos" href="http://mikiorbe.wordpress.com/tag/jquery/">jQuery</a>. Ahora vamos a ver cómo utilizar jQuery a través de CakePHP.</p>
<p>Dean Sofer comenta en <a title="Serving up actions as AJAX with jQuery in a few simple steps" href="http://bakery.cakephp.org/articles/view/serving-up-actions-as-ajax-with-jquery-in-a-few-simple-steps">Serving up actions as AJAX with jQuery in a few simple steps</a> (<img title="Inglés" src="http://mikiorbe.files.wordpress.com/2008/05/gb.gif?w=16&amp;h=11&#038;h=11" alt="Inglés" width="16" height="11" /> en inglés) que él no cree necesario un helper AJAX para jQuery (recordemos que el helper AJAX de CakePHP utiliza script.aculo.us) ya que un helper se utiliza para crear HTML y el javaScript debería estar lo más separado del HTML como sea posible (separación de funciones).</p>
<p>En este ejemplo vamos a modificar el código de nuestra aplicación de gestión de enlaces tal y como lo dejamos tras utilizar el formulario AJAX para insertar nuevos enlaces. Quitaremos todas las referencias al Helper de AJAX y le daremos la misma funcionalidad mediante jQuery.</p>
<p>Vamos a ver primero el controlador, explicando los cambios.</p>
<pre class="brush: php;">
&lt;?php
class LinksController extends AppController {

	var $name = 'Links';
	var $helpers = array('Html', 'Form', 'Javascript');
	var $components = array('RequestHandler');

	function add() {
		if (!empty($this-&gt;data)) {
			if ($this-&gt;Link-&gt;save($this-&gt;data)) {
				//$this-&gt;flash('Enlace añadido.','/links',3);
			}
		}
		$this-&gt;set('links', $this-&gt;Link-&gt;findAll());
		//$this-&gt;render('index', 'ajax');
		$this-&gt;render('list');
	}

	function index() {
		$this-&gt;set('links', $this-&gt;Link-&gt;findAll());
	}

}
?&gt;
</pre>
<ul>
<li>Eliminamos el helper de AJAX, aunque mantenemos el de JavaScript.</li>
<li>Añadimos el componente <code>RequestHandler</code>. Este componente identifica las peticiones vía AJAX para poder responder con el <a title="Layouts en CakePHP" href="http://book.cakephp.org/es/view/96/Layouts">layout</a> AJAX (por defecto vacío). Como ahora sólo vamos a hacer llamadas a <code>add()</code> mediante AJAX podríamos omitir este componente y realizar la llamada a la vista mediante <code>$this-&gt;render('list','ajax');</code> (hemos añadido el parámetro que indica el layout a utilizar).</li>
<li>Hemos cambiado la vista a mostrar por <code>list</code>, que veremos a continuación.</li>
</ul>
<p>Ahora vemos la vista principal (<em>/app/views/links/index.ctp</em>):</p>
<pre class="brush: xml;">
&lt;?php
echo $javascript-&gt;link('jquery-1.3.1.min.js',false);
echo $javascript-&gt;link('jquery.form.js',false);
?&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
$(document).ready(function() {
    var options = {
        target:'#links',
		clearForm: true
    }; 

    $('#newLinkForm').ajaxForm(options);
});
&lt;/script&gt;

&lt;h1&gt;Enlaces disponibles&lt;/h1&gt;
&lt;div id=&quot;links&quot;&gt;
&lt;?php echo $this-&gt;element('linksList', array('links' =&gt; $links)); ?&gt;
&lt;/div&gt;

&lt;h2&gt;Añadir enlace&lt;/h2&gt;
&lt;?php
echo $form-&gt;create('Link', array('action' =&gt; 'add', 'id' =&gt; 'newLinkForm'));
echo $form-&gt;input('title', array('label' =&gt; 'Nombre', 'error' =&gt; __('Titulo no valido', true)));
echo $form-&gt;input('url');
echo $form-&gt;submit('Añadir',array('escape'=&gt;false));
echo $form-&gt;end();
?&gt;
</pre>
<ul>
<li>Lógicamente he sustituido los links a script.aculo.us por los de jQuery. Utilizo el plugin <a title="jQuery Form Plugin" href="http://malsup.com/jquery/form/">jQuery Form Plugin</a> que me facilita la introducción de AJAX en el formulario.</li>
<li>Añado el código JavaScript prácticamente como aparece en la página de jQuery Form Plugin. En <code>target</code> se le indica el div en el que se va a introducir la respuesta (en este caso el que tenga id &#8220;links&#8221;). Al final le aplicamos el método <code>ajaxForm</code> al formulario con id &#8220;newLinkForm&#8221;.</li>
<li>He sustituido todo el listado de links por una llamada a un <a title="Elementos en CakePHP" href="http://book.cakephp.org/es/view/97/Elements">elemento CakePHP</a> pasándole unos datos (<code>$this-&gt;element('linkslist', array('links' =&gt; $links));</code>). Luego explicaré el por qué de este cambio.</li>
<li>La creación del formulario la hago como inicialmente mediante el helper de formularios (ya no mediante el de AJAX). Le pongo el id como parámetro.</li>
</ul>
<p>Vamos a ver ahora el elemento al que hacíamos referencia en la vista. Lo encontraremos en <em>/app/views/elements/linksList.ctp</em>.</p>
<pre class="brush: xml;">
&lt;?php foreach ($links as $link): ?&gt;
&lt;p&gt;
&lt;a href=&quot;&lt;?php echo $link['Link']['url']; ?&gt;&quot;&gt;&lt;?php echo $link['Link']['title']; ?&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Añadido: &lt;?php echo $link['Link']['created']; ?&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;?php foreach ($link['Comment'] as $comment): ?&gt;
&lt;li&gt;&lt;?php echo $comment['comment'] . ' (' . $comment['created'] . ')'; ?&gt;&lt;/li&gt;
&lt;?php endforeach; ?&gt;
&lt;li&gt;&lt;?php echo $html-&gt;link('Añadir comentario', '/comments/add/' . $link['Link']['id']);?&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;?php endforeach; ?&gt;
</pre>
<p>Como podemos ver es exactamente el mismo código que teníamos en la página principal y que generaba el listado de enlaces. Lo que hemos hecho es crear un elemento de CakePHP, es decir, una porción reutilizable. Y la reutilizamos en la página principal y en la nueva vista que hemos creado para la respuesta AJAX, que sólo tiene que contener el listado. Vemos dicha vista (<em>/app/views/links/list.ctp</em>) a continuación:</p>
<pre class="brush: php;">
&lt;?php echo $this-&gt;element('linkslist', array('links' =&gt; $links)); ?&gt;
</pre>
<p>Y con esto ya tenemos funcionando el formulario AJAX mediante jQuery.</p>
 Tagged: AJAX, CakePHP, JQuery, PHP <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mikiorbe.wordpress.com/560/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mikiorbe.wordpress.com/560/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mikiorbe.wordpress.com/560/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mikiorbe.wordpress.com/560/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mikiorbe.wordpress.com/560/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mikiorbe.wordpress.com/560/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mikiorbe.wordpress.com/560/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mikiorbe.wordpress.com/560/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mikiorbe.wordpress.com/560/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mikiorbe.wordpress.com/560/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikiorbe.wordpress.com&blog=3806599&post=560&subd=mikiorbe&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://mikiorbe.wordpress.com/2009/06/01/ajax-en-cakephp-mediante-jquery/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e0aa1c86de99e8f09a34f5849f358bcc?s=96&amp;d=identicon&amp;r=G" medium="image">
			<media:title type="html">mikiorbe</media:title>
		</media:content>

		<media:content url="http://mikiorbe.files.wordpress.com/2008/05/gb.gif?w=16&amp;h=11&amp;h=11" medium="image">
			<media:title type="html">Inglés</media:title>
		</media:content>
	</item>
		<item>
		<title>¡¡Cumplimos un añito!!</title>
		<link>http://mikiorbe.wordpress.com/2009/05/26/%c2%a1%c2%a1cumplimos-un-anito/</link>
		<comments>http://mikiorbe.wordpress.com/2009/05/26/%c2%a1%c2%a1cumplimos-un-anito/#comments</comments>
		<pubDate>Tue, 26 May 2009 05:48:07 +0000</pubDate>
		<dc:creator>Miguel</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://mikiorbe.wordpress.com/?p=553</guid>
		<description><![CDATA[Pues hoy hace un año de la primera entrada que puse en mi blog, mi pequeña presentación.

Hoy un año después hago un pequeño análisis de este primer año de Tus ceros y Mis Unos.
En primer lugar, decir que estoy bastante satisfecho del camino recorrido. Me propuse crear el blog para obligarme a seguir aprendiendo, para [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikiorbe.wordpress.com&blog=3806599&post=553&subd=mikiorbe&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Pues hoy hace un año de la primera entrada que puse en mi blog, <a title="Mi presentación en Tus Ceros y Mis Unos" href="http://mikiorbe.wordpress.com/2008/05/26/presentacion/">mi pequeña presentación</a>.</p>
<p><img class="aligncenter size-full wp-image-556" title="1076967_94588268_400x300" src="http://mikiorbe.files.wordpress.com/2009/05/1076967_94588268_400x300.jpg?w=400&#038;h=300" alt="1076967_94588268_400x300" width="400" height="300" /><br />
Hoy un año después hago un pequeño análisis de este primer año de Tus ceros y Mis Unos.</p>
<p>En primer lugar, decir que estoy bastante satisfecho del camino recorrido. Me propuse crear el blog para obligarme a seguir aprendiendo, para mejorar mi visibilidad como profesional y para devolver a la comunidad parte de lo aprendido de ella. En general creo que mis expectativas al respecto se han cumplido.</p>
<p>En su día pensaba mantener un ritmo de una o dos entradas semanales, lo que evidentemente no he cumplido. Sin embargo he publicado 37 entradas en total (aunque 3 ó 4 de avisos o generalistas) todas de factura propia que siempre tienen más trabajo que traducir o enlazar a entradas en inglés (en si día contaba con traducir de vez en cuando).</p>
<p>En cuanto a datos de acceso, pues también estoy contento, ya que parece que mi esfuerzo le es útil a otras personas. Tengo un promedio entre 60 y 80 visitas diarias con un record de 161 visitas en un día y 12.987 visitas totales. No tengo ni idea sobre los datos de otros blogs de temática similar, pero para mí cumple mis expectativas.</p>
<p>En cuanto a temas, <a title="CakePHP en tus Ceros y Mis Unos" href="http://mikiorbe.wordpress.com/tag/cakephp/">CakePHP</a> y <a title="OSGi en Tus Ceros y Mis Unos" href="http://mikiorbe.wordpress.com/tag/osgi/">OSGi</a> se han llevado la palma.</p>
<p>Para el futuro intentaré seguir el ritmo de una entrada semanal. Los temas seguirán en la línea de lo ya publicado, seguiremos ampliando algunos temas y descubriremos cosas nuevas (según se me vaya presentando).</p>
<p>Por último daros las gracias a todos los que visitáis tus Ceros y Mis Unos, ¡permaneced a la escucha!.</p>
 Tagged: General <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mikiorbe.wordpress.com/553/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mikiorbe.wordpress.com/553/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mikiorbe.wordpress.com/553/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mikiorbe.wordpress.com/553/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mikiorbe.wordpress.com/553/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mikiorbe.wordpress.com/553/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mikiorbe.wordpress.com/553/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mikiorbe.wordpress.com/553/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mikiorbe.wordpress.com/553/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mikiorbe.wordpress.com/553/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikiorbe.wordpress.com&blog=3806599&post=553&subd=mikiorbe&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://mikiorbe.wordpress.com/2009/05/26/%c2%a1%c2%a1cumplimos-un-anito/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e0aa1c86de99e8f09a34f5849f358bcc?s=96&amp;d=identicon&amp;r=G" medium="image">
			<media:title type="html">mikiorbe</media:title>
		</media:content>

		<media:content url="http://mikiorbe.files.wordpress.com/2009/05/1076967_94588268_400x300.jpg" medium="image">
			<media:title type="html">1076967_94588268_400x300</media:title>
		</media:content>
	</item>
		<item>
		<title>Formulario AJAX en CakePHP</title>
		<link>http://mikiorbe.wordpress.com/2009/05/05/formulario-ajax-en-cakephp/</link>
		<comments>http://mikiorbe.wordpress.com/2009/05/05/formulario-ajax-en-cakephp/#comments</comments>
		<pubDate>Tue, 05 May 2009 19:40:52 +0000</pubDate>
		<dc:creator>Miguel</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[CakePHP]]></category>

		<guid isPermaLink="false">http://mikiorbe.wordpress.com/?p=539</guid>
		<description><![CDATA[En esta nueva entrada dedicada a CakePHP voy a explicar cómo utilizar un poco de AJAX en nuestra aplicación. AJAX realiza peticiones al servidor en segundo plano, por lo que partes de la página se pueden ir refrescando sin tener que recargar la página entera.
Voy a utilizar el ejemplo del gestor de enlaces que ya [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikiorbe.wordpress.com&blog=3806599&post=539&subd=mikiorbe&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>En esta nueva entrada dedicada a <a title="CakePHP" href="http://cakephp.org/">CakePHP</a> voy a explicar cómo utilizar un poco de <a title="AJAX en Wikipedia ES" href="http://es.wikipedia.org/wiki/AJAX">AJAX</a> en nuestra aplicación. AJAX realiza peticiones al servidor en segundo plano, por lo que partes de la página se pueden ir refrescando sin tener que recargar la página entera.</p>
<p>Voy a utilizar el ejemplo del gestor de enlaces que ya tenía en marcha en anteriores <a title="Entradas sobre CakePHP en TCYMU" href="http://mikiorbe.wordpress.com/tag/cakephp/">entradas de CakePHP en Tus Ceros Y Mis Unos</a>. En concreto voy a facilitar el agregar nuevos enlaces pasando el formulario de añadir enlace a la página principal, de forma que al completar dicho formulario se refresque en el listado sin recargar la página completa.</p>
<p>El <a title="Helper de AJAX en CakePHP" href="http://book.cakephp.org/view/208/AJAX">ayudante (&#8220;helper&#8221;) de AJAX en CakePHP</a> utiliza las librerías JavaScript <a title="script.aculo.us" href="http://script.aculo.us/">script.aculo.us</a> y <a title="Prototype" href="http://prototypejs.org/">Prototype</a>. Nos descargamos la última versión estable de script.aculo.us (la 1.8.2 en el momento de escribir esta entrada) ya que incluye Prototype. Copiamos tanto el fichero de Prototype (en lib dentro de la carpeta de script.aculo.us) como todos los ficheros propios de script.aculo.us (en src) a la carpeta de JavaScript de nuestra aplicación CakePHP: <code>/app/webroot/js</code>.</p>
<p>Insertamos en la plantilla por defecto de nuestro sitio web (<code>/app/views/layouts/default.thtml</code>) una línea para que CakePHP sepa dónde insertar los scripts posteriormente. La línea es <code>&lt;?php echo $scripts_for_layout ?&gt;</code> al igual que teníamos <code>&lt;?php echo $content_for_layout ?&gt;</code> que indicaba dónde insertar el contenido:</p>
<pre class="brush: xml;">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;

&lt;head&gt;
	&lt;title&gt;TCYMU CakePHP Gestión de Enlaces&lt;/title&gt;
	&lt;?php echo $scripts_for_layout ?&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;h1&gt;Tus ceros y mis unos&lt;/h1&gt;
	&lt;h2&gt;Gestión de enlaces&lt;/h2&gt;

	&lt;?php echo $content_for_layout ?&gt;

	&lt;h3&gt;TCYMU por Miguel Orbegozo&lt;/h3&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>Ahora es el momento de modificar el controlador de nuestra aplicación. Primero enumero los cambios y luego muestro el código completo. Las modificaciones son las siguientes:</p>
<ol>
<li>Definimos la variable <code>helpers</code> con los ayudantes que se utilizan. Si no sobrescribimos la variable se incluyen el de HTML y el de formularios. Además queremos añadir el de JavaScript y el de AJAX.<br />
<code>var $helpers = array('Html', 'Form', 'Javascript', 'Ajax');</code></li>
<li>Modificamos la función <code>add</code>, ya que ahora responderá a una petición AJAX. Lo que hacemos tras insertar el contenido del formulario (exactamente igual que antes) es obtener la lista de enlaces (igual que en la función <code>index</code>) y mostrar la vista <code>index</code>, con la particularidad de que le pasamos el parámetro <code>'ajax'</code> para que sepa que es una respuesta a una petición AJAX.</li>
</ol>
<pre class="brush: php;">
&lt;?php
class LinksController extends AppController {

	var $name = 'Links';
	var $helpers = array('Html', 'Form', 'Javascript', 'Ajax');

	function add() {
		if (!empty($this-&gt;data)) {
			if ($this-&gt;Link-&gt;save($this-&gt;data)) {
				//$this-&gt;flash('Enlace añadido.','/links',3);
			}
		}
		$this-&gt;set('links', $this-&gt;Link-&gt;findAll());
		$this-&gt;render('index', 'ajax');
	}

	function index() {
		$this-&gt;set('links', $this-&gt;Link-&gt;findAll());
	}

}
?&gt;
</pre>
<p>Ahora modificaremos la vista de nuestra página de inicio (<code>/app/views/links/index.thtml</code>). Como antes primero se enumeran los cambios para después ver el código en su totalidad.</p>
<ol>
<li>Añado las librerías JavaScript mediante el método de AjaxHelper <code>link</code>.<br />
<code>&lt;?php<br />
echo $javascript-&gt;link('prototype.js',false);<br />
echo $javascript-&gt;link('scriptaculous.js?load=effects',false);<br />
?&gt;</code><br />
Dos pequeños detalles. El segundo parámetro hace que se añadan en la cabecera (en <code>$scripts_for_layout</code> que definimos antes). Al poner <code>scriptaculous.js?load=effects</code> hacemos que sólo se carguen los scripts de efectos, ya que si sólo hubiéramos puesto <code>scriptaculous</code> carga todos los ficheros de script.aculo.us</li>
<li>La lista de enlaces la vamos a situar en un <code>div</code> con un identificador determinado, ya que esta será la parte que se refresque tras la petición AJAX. Lo creamos mediante el ayudante de AJAX y sus métodos <code>div</code> y <code>divEnd</code>.<br />
<code>&lt;?php echo $ajax-&gt;div('links'); ?&gt;<br />
...<br />
&lt;?php echo $ajax-&gt;divEnd('links'); ?&gt;</code></li>
<li>Sustituimos el enlace que nos llevaba a la página de añadir enlace por el formulario que aparecía en esta página.</li>
<li>Sustituimos la creación del formulario. En lugar de utilizar el método <code>form</code> del ayudante de formularios utilizaremos el método <code>form</code> pero del ayudante de AJAX. A este método se le pasa la función del controlador, el tipo de envío (&#8220;get&#8221; o &#8220;post&#8221;) y un array de opciones en el que en <code>update</code> le indicamos el <code>div</code> que debe refrescar.<br />
<code>echo $ajax-&gt;form('/add', 'post', array('update' =&gt; 'links'));</code></li>
</ol>
<pre class="brush: xml;">
&lt;?php
echo $javascript-&gt;link('prototype.js',false);
echo $javascript-&gt;link('scriptaculous.js?load=effects',false);
?&gt;

&lt;h1&gt;Enlaces disponibles&lt;/h1&gt;

&lt;?php echo $ajax-&gt;div('links'); ?&gt;
&lt;?php foreach ($links as $link): ?&gt;
&lt;p&gt;
&lt;a href=&quot;&lt;?php echo $link['Link']['url']; ?&gt;&quot;&gt;&lt;?php echo $link['Link']['title']; ?&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Añadido: &lt;?php echo $link['Link']['created']; ?&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;?php foreach ($link['Comment'] as $comment): ?&gt;
&lt;li&gt;&lt;?php echo $comment['comment'] . ' (' . $comment['created'] . ')'; ?&gt;&lt;/li&gt;
&lt;?php endforeach; ?&gt;
&lt;li&gt;&lt;?php echo $html-&gt;link('Añadir comentario', '/comments/add/' . $link['Link']['id']);?&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;?php endforeach; ?&gt;
&lt;?php echo $ajax-&gt;divEnd('links'); ?&gt;

&lt;h2&gt;Añadir enlace&lt;/h2&gt;
&lt;?php
echo $ajax-&gt;form('/add', 'post', array('update' =&gt; 'links'));
echo $form-&gt;input('title', array('label' =&gt; 'Nombre', 'error' =&gt; __('Titulo no valido', true)));
echo $form-&gt;input('url');
echo $form-&gt;submit('Añadir',array('escape'=&gt;false));
echo $form-&gt;end();
?&gt;
</pre>
<p>Con estos cambios ya se actualizará nuestra lista de enlaces tras rellenar el formulario y sin recargar la página. Misión cumplida.</p>
 Tagged: AJAX, CakePHP, PHP <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mikiorbe.wordpress.com/539/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mikiorbe.wordpress.com/539/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mikiorbe.wordpress.com/539/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mikiorbe.wordpress.com/539/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mikiorbe.wordpress.com/539/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mikiorbe.wordpress.com/539/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mikiorbe.wordpress.com/539/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mikiorbe.wordpress.com/539/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mikiorbe.wordpress.com/539/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mikiorbe.wordpress.com/539/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikiorbe.wordpress.com&blog=3806599&post=539&subd=mikiorbe&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://mikiorbe.wordpress.com/2009/05/05/formulario-ajax-en-cakephp/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e0aa1c86de99e8f09a34f5849f358bcc?s=96&amp;d=identicon&amp;r=G" medium="image">
			<media:title type="html">mikiorbe</media:title>
		</media:content>
	</item>
		<item>
		<title>Linux para niños</title>
		<link>http://mikiorbe.wordpress.com/2009/04/24/linux-para-ninos/</link>
		<comments>http://mikiorbe.wordpress.com/2009/04/24/linux-para-ninos/#comments</comments>
		<pubDate>Fri, 24 Apr 2009 10:04:37 +0000</pubDate>
		<dc:creator>Miguel</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://mikiorbe.wordpress.com/?p=532</guid>
		<description><![CDATA[Mi hijo (4 años) tiene un usuario (¡se sabe su contraseña y todo!) en el Ubuntu que tengo en casa. Le tengo puesto un fondo de escritorio de su gusto y sabe lanzar GCompriss que es la única aplicación que utiliza. De momento eso es todo, pero él se lo pasa muy bien cuando se [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikiorbe.wordpress.com&blog=3806599&post=532&subd=mikiorbe&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Mi hijo (4 años) tiene un usuario (¡se sabe su contraseña y todo!) en el <a title="Ubuntu" href="http://www.ubuntu.com/">Ubuntu</a> que tengo en casa. Le tengo puesto un fondo de escritorio de su gusto y sabe lanzar <a title="GCompriss" href="http://gcompris.net/-es-">GCompriss</a> que es la única aplicación que utiliza. De momento eso es todo, pero él se lo pasa muy bien cuando se pone.</p>
<p style="text-align:center;"><img class="size-full wp-image-534 aligncenter" title="tux-edubuntu" src="http://mikiorbe.files.wordpress.com/2009/04/tux-edubuntu.png?w=247&#038;h=250" alt="tux-edubuntu" width="247" height="250" /></p>
<p>El caso es que como ese Ubuntu es en cierto modo experimental (al menos hasta que consiga desbancar a <a title="OpenSUSE" href="http://es.opensuse.org/">openSUSE</a> en mis preferencias) estaba buscando una distribución completa para dejarla de manera más estable en una partición pequeña. Y ya puestos lo mejor era buscar una distribución orientada a niños. Aquí os presento un pequeño resumen de mi búsqueda.  Las distribuciones con este perfil que he encontrado son:</p>
<ul>
<li><a title="Edubuntu" href="http://www.edubuntu.com/">Edubuntu</a>: Amparada por la todopoderosa Ubuntu. Incluye GCompriss y el <a title="Paquete educativo de KDE" href="http://edu.kde.org/">paquete educativo de KDE</a> (que también tiene muy buena pinta) entre otras (ver <a title="Lista de aplicaciones en Edubuntu" href="http://www.edubuntu.org/applications">lista de aplicaciones</a>). Su instalación parte de un Ubuntu desktop instalado ya que lo que descargaremos será una serie de paquetes y no un sistema entero. Tiene soporte para instalación en un entorno educativo con un servidor y clientes ligeros (<a title="LTSP en Wikipedia ES" href="http://es.wikipedia.org/wiki/LTSP">LTSP</a>).</li>
<li><a title="Foresight Kid's Edition" href="http://www.foresightlinux.org/kids.html">Foresight Kid&#8217;s Edition</a>: Subproyecto de <a title="Foresight" href="http://www.foresightlinux.org/index.html">Foresight</a>, una distribución basada en el administrador de paquetes Conary. No falta GCompriss. En el siguiente enlace podemos ver un <a title="Análisis de Foresight Kid's Edition" href="http://www.linux.com/feature/148942">análisis de Foresight Kid&#8217;s Edition</a> (<img class="alignnone size-full wp-image-9" title="Inglés" src="http://mikiorbe.files.wordpress.com/2008/05/gb.gif?w=16&#038;h=11" alt="Inglés" width="16" height="11" /> en inglés).</li>
<li><a title="Qimo for kids" href="http://www.qimo4kids.com/default.aspx">Qimo for kids</a>: Una reciente distribución que se basa también en Ubuntu. Como dicen en su web, se diferencian de Edubuntu en que se instala directamente (no necesita un Ubuntu instalado) y que no busca el soporte de entorno con clientes ligeros.</li>
<p style="text-align:center;"><img class="alignnone size-full wp-image-536" title="qimo" src="http://mikiorbe.files.wordpress.com/2009/04/qimo.jpg?w=450&#038;h=339" alt="qimo" width="450" height="339" /></p>
<li><a title="ZenEdu Live" href="http://wiki.zenwalk.org/index.php?title=ZenEdu_Live">ZenEdu Live</a>: Está en pausa según su web y por tanto no lo considero una opción.</li>
<li><a title="Debian Jr." href="http://wiki.debian.org/DebianJr">Debian Jr.</a>: Es lo que llaman una mezcla de Debian (<a title="Debian Pure Blend" href="http://wiki.debian.org/DebianPureBlends">Debian Pure Blend</a>), es decir un empaquetado especial de Debian dirigido a un sector específico (en este caso los niños). Está en desarrollo pero todavía no tienen imágenes finales por lo que no lo considero todavía una opción.</li>
</ul>
<p>Como vemos, al final tenemos tres distribuciones a probar. Edubuntu, Qimo y Foresight Kid&#8217;s, aunque las pruebas quedarían para una segunda entrada.  Si alguien conoce alguna otra distribución que incluir en la lista que me lo haga saber por favor.</p>
 Tagged: Linux <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mikiorbe.wordpress.com/532/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mikiorbe.wordpress.com/532/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mikiorbe.wordpress.com/532/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mikiorbe.wordpress.com/532/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mikiorbe.wordpress.com/532/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mikiorbe.wordpress.com/532/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mikiorbe.wordpress.com/532/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mikiorbe.wordpress.com/532/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mikiorbe.wordpress.com/532/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mikiorbe.wordpress.com/532/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikiorbe.wordpress.com&blog=3806599&post=532&subd=mikiorbe&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://mikiorbe.wordpress.com/2009/04/24/linux-para-ninos/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e0aa1c86de99e8f09a34f5849f358bcc?s=96&amp;d=identicon&amp;r=G" medium="image">
			<media:title type="html">mikiorbe</media:title>
		</media:content>

		<media:content url="http://mikiorbe.files.wordpress.com/2009/04/tux-edubuntu.png" medium="image">
			<media:title type="html">tux-edubuntu</media:title>
		</media:content>

		<media:content url="http://mikiorbe.files.wordpress.com/2008/05/gb.gif" medium="image">
			<media:title type="html">Inglés</media:title>
		</media:content>

		<media:content url="http://mikiorbe.files.wordpress.com/2009/04/qimo.jpg" medium="image">
			<media:title type="html">qimo</media:title>
		</media:content>
	</item>
		<item>
		<title>Introducción a Terracotta (y 2)</title>
		<link>http://mikiorbe.wordpress.com/2009/04/16/introduccion-a-terracotta-y-2/</link>
		<comments>http://mikiorbe.wordpress.com/2009/04/16/introduccion-a-terracotta-y-2/#comments</comments>
		<pubDate>Thu, 16 Apr 2009 10:39:33 +0000</pubDate>
		<dc:creator>Miguel</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Terracotta]]></category>

		<guid isPermaLink="false">http://mikiorbe.wordpress.com/?p=515</guid>
		<description><![CDATA[En la anterior entrada sobre Terracotta pusimos un pequeño ejemplo con un servidor y tres clientes (un productor de tareas y dos consumidores), aunque todo corriendo en la misma máquina. Además también dejamos el ejemplo dando un feo aviso porque todos los clientes intentaba utilizar el mismo archivo de log.
En esta pequeña continuación vamos a [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikiorbe.wordpress.com&blog=3806599&post=515&subd=mikiorbe&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>En la anterior <a title="Introducción a Terracotta" href="http://mikiorbe.wordpress.com/2009/03/31/introduccion-a-terracotta-cluster-a-nivel-maquina-virtual/">entrada sobre Terracotta</a> pusimos un pequeño ejemplo con un servidor y tres clientes (un productor de tareas y dos consumidores), aunque todo corriendo en la misma máquina. Además también dejamos el ejemplo dando un feo aviso porque todos los clientes intentaba utilizar el mismo archivo de log.</p>
<p>En esta pequeña continuación vamos a utilizar el mismo ejemplo pero lo iremos mejorando, primero eliminando el aviso de los logs y después utilizando varias máquinas.</p>
<p style="text-align:center;"><img class="size-full wp-image-520 aligncenter" title="terracotta" src="http://mikiorbe.files.wordpress.com/2009/04/samples.png?w=222&#038;h=27" alt="terracotta" width="222" height="27" /></p>
<p>Para llevar a cabo esta tarea vamos a utilizar un único <em>tc-config.xml</em>, que lo cargará el servidor y los clientes lo tomarán de él. Para ello es necesario arrancar el servidor (<code>start-tc-server</code>) desde el directorio en el que tenemos el <em>tc-config.xml</em> o mediante la opción <code>-f</code>:</p>
<p><code>start-tc-server.bat -f /ruta/al/fichero/tc-config.xml</code> (será .bat o .sh según estemos en Windows o Unix)</p>
<p>Pero antes vamos a hacer unos cambios en el archivo de configuración. Le vamos a añadir la lista de servidores y le vamos a configurar el directorio de logs en función de una variable de entorno. En la web de Terracotta tenemos una <a title="Guía y referencia de la configuración de Terracotta" href="http://www.terracotta.org/web/display/docs/Configuration+Guide+and+Reference#ConfigurationGuideandReference-ServersConfigurationSection">guía y referencia de la configuración</a> en la que podemos ver las descripciones de esos campos y muchos otros.</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;tc:tc-config xmlns:tc=&quot;http://www.terracotta.org/config&quot;&gt;
  &lt;servers&gt;
    &lt;server host=&quot;169.254.122.220&quot;/&gt;
  &lt;/servers&gt;
  &lt;clients&gt;
    &lt;logs&gt;logs-%(tcymu_name)&lt;/logs&gt;
  &lt;/clients&gt;
  &lt;application&gt;
    &lt;dso&gt;
      &lt;roots&gt;
        &lt;root&gt;
          &lt;field-name&gt;org.tcymu.terracotta.TasksQueue.queue&lt;/field-name&gt;
        &lt;/root&gt;
      &lt;/roots&gt;
      &lt;instrumented-classes&gt;
        &lt;include&gt;&lt;class-expression&gt;org.tcymu.terracotta.Task&lt;/class-expression&gt;&lt;/include&gt;
      &lt;/instrumented-classes&gt;
    &lt;/dso&gt;
  &lt;/application&gt;
&lt;/tc:tc-config&gt;
</pre>
<p>Como vemos hemos añadido la sección de servidores y la de clientes. En la de servidores ponemos la <a title="Dirección IP en Wikipedia ES" href="http://es.wikipedia.org/wiki/Direcci%C3%B3n_IP">dirección IP</a> de nuestro único servidor. En la parte de clientes configuramos el nombre del fichero de logs en función de la variable de entorno <em>tcymu_name</em>.</p>
<p>Ya podemos arrancar el servidor como hemos visto un poco más arriba. También arrancamos el generador de tareas con el comando mostrado a continuación:</p>
<p><code>dso-java.bat -Dtc.config=169.254.122.220:9510 -Dtcymu_name=creator -cp classes org.tcymu.terracotta.TaskCreator</code></p>
<p>Las diferencias con respecto al que utilizamos en la primera parte son:</p>
<ul>
<li> Se le pasa la dirección del servidor (con su puerto por defecto en este caso) de la que va a tomar el <em>tc.config.xml</em>.</li>
<li> Se le pasa la variable de entorno que se utiliza para nombrar el archivo de logs.</li>
</ul>
<p>Utilizaremos un comando similar para arrancar el primero de los consumidores de tareas, variando sólo la clase a arrancar y el valor de la variable de entorno para el fichero de logs.</p>
<p>Por supuesto al tomar el <em>tc.config.xml</em> de un servidor a través de una dirección IP podemos arrancar el segundo consumidor en otra máquina (en este caso un <a title="OpenSUSE" href="http://es.opensuse.org/">openSUSE</a> virtualizado sobre <a title="VirtualBox" href="http://www.virtualbox.org/">VirtualBox</a>):</p>
<p><code>dso-java.sh -Dtc.config=169.254.122.220:9510 -Dtcymu_name=resolver2 -cp classes org.tcymu.terracotta.TaskResolver</code></p>
<p style="text-align:center;"><a href="http://mikiorbe.files.wordpress.com/2009/04/terracotta2_1.png"><img class="size-medium wp-image-518 aligncenter" title="terracotta2_1" src="http://mikiorbe.files.wordpress.com/2009/04/terracotta2_1.png?w=300&#038;h=73" alt="terracotta2_1" width="300" height="73" /></a></p>
<p>Con esto terminamos esta pequeña continuación.</p>
 Tagged: Java, Terracotta <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mikiorbe.wordpress.com/515/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mikiorbe.wordpress.com/515/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mikiorbe.wordpress.com/515/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mikiorbe.wordpress.com/515/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mikiorbe.wordpress.com/515/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mikiorbe.wordpress.com/515/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mikiorbe.wordpress.com/515/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mikiorbe.wordpress.com/515/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mikiorbe.wordpress.com/515/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mikiorbe.wordpress.com/515/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikiorbe.wordpress.com&blog=3806599&post=515&subd=mikiorbe&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://mikiorbe.wordpress.com/2009/04/16/introduccion-a-terracotta-y-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e0aa1c86de99e8f09a34f5849f358bcc?s=96&amp;d=identicon&amp;r=G" medium="image">
			<media:title type="html">mikiorbe</media:title>
		</media:content>

		<media:content url="http://mikiorbe.files.wordpress.com/2009/04/samples.png" medium="image">
			<media:title type="html">terracotta</media:title>
		</media:content>

		<media:content url="http://mikiorbe.files.wordpress.com/2009/04/terracotta2_1.png?w=300" medium="image">
			<media:title type="html">terracotta2_1</media:title>
		</media:content>
	</item>
		<item>
		<title>Introducción a Terracotta: cluster a nivel máquina virtual</title>
		<link>http://mikiorbe.wordpress.com/2009/03/31/introduccion-a-terracotta-cluster-a-nivel-maquina-virtual/</link>
		<comments>http://mikiorbe.wordpress.com/2009/03/31/introduccion-a-terracotta-cluster-a-nivel-maquina-virtual/#comments</comments>
		<pubDate>Tue, 31 Mar 2009 16:31:52 +0000</pubDate>
		<dc:creator>Miguel</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Terracotta]]></category>

		<guid isPermaLink="false">http://mikiorbe.wordpress.com/?p=486</guid>
		<description><![CDATA[En esta entrada voy a presentaros Terracotta. Terracotta se distribuye bajo una doble licencia libre-comercial.  Terracotta es una herramienta de cluster a nivel de máquina virtual Java (JVM) o como dicen en su web una memoria distribuida en red o NAM (Network Attached Memory por similitud con Network Attached Storage). Esto quiere decir que [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikiorbe.wordpress.com&blog=3806599&post=486&subd=mikiorbe&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>En esta entrada voy a presentaros <a title="Terracotta" href="http://www.terracotta.org/">Terracotta</a>. Terracotta se distribuye bajo una <a title="Licencia de Terracotta" href="http://www.terracotta.org/web/display/orgsite/Licensing">doble licencia</a> libre-comercial.  Terracotta es una herramienta de <a title="Cluster en Wikipedia ES" href="http://es.wikipedia.org/wiki/Cluster_(inform%C3%A1tica)">cluster</a> a nivel de máquina virtual Java (JVM) o como dicen en su web una memoria distribuida en red o NAM (Network Attached Memory por similitud con <a title="NAS en Wikipedia ES" href="http://es.wikipedia.org/wiki/Network-attached_storage">Network Attached Storage</a>). Esto quiere decir que podemos compartir objetos o parámetros de objetos entre distintas máquinas virtuales Java, incluso corriendo en distintas máquinas.  Esto se logra mediante una arquitectura cliente-servidor (transparente a nuestra aplicación) por un lado y un cargador de clases (<a title="ClassLoader en Wikipedia EN" href="http://en.wikipedia.org/wiki/Classloader">ClassLoader</a>) especial. Terracotta también permite &#8220;clusterizar&#8221; ese servidor que hemos nombrado para entornos de alta disponibilidad. Señalar también que Terracotta no utiliza la serialización Java si no un intercambio de los parámetros que se modifican en cada caso, de forma que se minimice el tráfico en la red.  Tras esta pequeña introducción teórica vamos a ver un pequeño ejemplo. Creamos una pequeña clase que representa una tarea a realizar por nuestra aplicación:</p>
<pre class="brush: java;">
package org.tcymu.terracotta;

public class Task {
	private long duration;
	private long id;

	public Task(long id, long duration) {
		this.id = id;
		this.duration = duration;
		System.out.println(&quot;Nueva tarea &quot; + id + &quot; de duracion &quot; + duration);
	}

	public void run() {
		System.out.println(&quot;Iniciando tarea &quot; + id + &quot; de duracion &quot; + duration);
		try {
			Thread.sleep(duration);
		} catch (Exception e) {}
		System.out.println(&quot;Finalizando tarea &quot; + id);
	}

}
</pre>
<p>y una que representa la cola con las tareas que hay que realizar:</p>
<pre class="brush: java;">
package org.tcymu.terracotta;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class TasksQueue {
	private static TasksQueue instance;
	private BlockingQueue queue = new LinkedBlockingQueue(5);

	public static TasksQueue getInstance() {
		if (instance == null) {
			instance = new TasksQueue();
		}
		return instance;
	}

	private TasksQueue() {
	}

	public BlockingQueue getQueue() {
		return queue;
	}
}
</pre>
<p>Finalmente, creamos otras dos clases, una crea tareas y otra las resuelve:</p>
<pre class="brush: java;">
package org.tcymu.terracotta;

import java.util.Random;

public class TaskCreator {
	private static long id = 1;

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Random random = new Random();
		TasksQueue tasksQueue = TasksQueue.getInstance();
		tasksQueue.getQueue().clear();
		while (true) {
			//Duracion aleatoria 1 a 10 segundos
			long duraction = (random.nextInt(10) + 1) * 1000;
			try {
				tasksQueue.getQueue().put(new Task(id++, duraction));
				Thread.sleep(3000); //Una tarea cada 3 segundos
			} catch (InterruptedException e) {}
		}
	}
}
</pre>
<pre class="brush: java;">
package org.tcymu.terracotta;

public class TaskResolver {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		TasksQueue tasksQueue = TasksQueue.getInstance();
		while (true) {
			try {
				Task task = tasksQueue.getQueue().take();
				task.run();
			} catch (InterruptedException e) {}
		}
	}
}
</pre>
<p>Como podemos ver, son clases normales, sin nada especial que resaltar. Eso sí, si ejecutamos el creador de tareas o el consumidor, lógicamente vemos que no se relacionan entre ellas. Las vamos a relacionar mediante Terracotta, y el vínculo entre ellas será la cola que es el elemento común.</p>
<p>Lo primero que necesitamos es descargarnos la edición libre (ES) desde la <a title="Descargas de Terracotta" href="http://www.terracotta.org/web/display/orgsite/DownloadCatalog">sección de descargas de Terracotta</a>. Yo he utilizado la versión <em>ES 2.7.3</em>. Aparte de eso, lo único que he hecho es añadir el directorio <em>bin</em> de Terracotta al <a title="Path en Wikipedia EN" href="http://en.wikipedia.org/wiki/Path_(variable)">path</a> para poder utilizar sus comandos más cómodamente.  Como hemos dicho, Terracotta necesita un servidor y es el momento de arrancarlo. Para ello abrimos una consola y ejecutamos el script <code>start-tc-server</code> (está en el directorio bin que hemos añadido al path y existe en versión windows y versión unix/linux).</p>
<p style="text-align:center;"><a href="http://mikiorbe.files.wordpress.com/2009/03/terracotta_1.png"><img class="size-medium wp-image-504 aligncenter" title="terracotta_1" src="http://mikiorbe.files.wordpress.com/2009/03/terracotta_1.png?w=300&#038;h=148" alt="terracotta_1" width="300" height="148" /></a></p>
<p>Ahora creamos el archivo de configuración que le indica a Terracotta cuáles son los que se guardan en la memoria de red. El fichero lo llamo <em>tc-config.xml</em> y lo voy a poner en el raíz  de mi proyecto Eclipse, aunque podría ir en cualquier sitio:</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;tc:tc-config xmlns:tc=&quot;http://www.terracotta.org/config&quot;&gt;
  &lt;application&gt;
    &lt;dso&gt;
      &lt;roots&gt;
        &lt;root&gt;
          &lt;field-name&gt;org.tcymu.terracotta.TasksQueue.queue&lt;/field-name&gt;
        &lt;/root&gt;
      &lt;/roots&gt;
      &lt;instrumented-classes&gt;
        &lt;include&gt;&lt;class-expression&gt;org.tcymu.terracotta.Task&lt;/class-expression&gt;&lt;/include&gt;
      &lt;/instrumented-classes&gt;
    &lt;/dso&gt;
  &lt;/application&gt;
&lt;/tc:tc-config&gt;
</pre>
<p>Primero le indicamos el objeto raíz que forma el cluster (cualquier cosa que se obtenga a partir de ese objeto también forma parte del cluster). También le indicamos las clases que Terracotta tiene que controlar (instrumented-classes), la clase Task al formar parte del cluster debe ser instrumentalizada.  Para arrancar el creador de tareas ejecuto el siguiente comando en una consola situada en el raíz del proyecto:</p>
<p><code>dso-java -cp classes org.tcymu.terracotta.TaskCreator</code></p>
<p>El comando <code>dso-java</code> es un comando de Terracotta que tras preparar el entorno para la ejecución en cluster llama al comando <code>java</code> de manera normal. Por eso con esa línea estamos fijando el classpath (a <em>classes</em> en este caso) y ejecutando la clase <code>TaskCreator</code>.</p>
<p>Hay que señalar que <code>dso-java</code> (y también  <code>start-tc-server</code>) toman el fichero <em>tc-config.xml</em> del directorio desde el que se llama (aunque hay otras opciones de <a title="Ficheros de conficuración de Terracotta" href="http://www.terracotta.org/web/display/docs/About+Terracotta+Configuration+Files">trabajar con los ficheros de configuración de Terracotta</a>). Por eso ejecuto el comando lo he ejecutado en el raíz del proyecto donde está el <em>tc-config</em> y el directorio <em>classes</em> con la compilación de las clases que hace Eclipse. Sin embargo el servidor lo he ejecutado desde cualquier consola, de forma que arranca sin tomar ese <em>tc-config</em>. El resultado de la ejecución en el que podemos ver cómo se crean tareas es:</p>
<p style="text-align:center;"><a href="http://mikiorbe.files.wordpress.com/2009/03/terracotta_2.png"><img class="size-medium wp-image-505 aligncenter" title="terracotta_2" src="http://mikiorbe.files.wordpress.com/2009/03/terracotta_2.png?w=300&#038;h=191" alt="terracotta_2" width="300" height="191" /></a></p>
<p>Y ahora arrancamos el consumidor de tareas, también desde una consola situada en el raíz del proyecto. Utilizamos el siguiente comando:</p>
<p><code>dso-java -cp classes org.tcymu.terracotta.TaskResolver</code></p>
<p style="text-align:center;"><a href="http://mikiorbe.files.wordpress.com/2009/03/terracotta_3.png"><img class="size-medium wp-image-506 aligncenter" title="terracotta_3" src="http://mikiorbe.files.wordpress.com/2009/03/terracotta_3.png?w=300&#038;h=267" alt="terracotta_3" width="300" height="267" /></a></p>
<p>Podemos ver que lo único que cambia es la clase a ejecutar. Nos aparece un aviso respecto a que el archivo de logs está en uso, lo que se debe a que hemos arrancado varios nodos en la misma máquina. De momento no me preocupo por ello.  Nuestro consumidor empieza a resolver tareas, aunque muy probablemente no a una velocidad suficiente.  Es el momento de escalar nuestra aplicación y arrancar un segundo consumidor. Abrimos otra consola nuevamente en el directorio raíz y volvemos a ejecutar el comando de arranque del consumidor. Ahora vemos que los consumidores van resolviendo tareas simultáneamente, lo que sin duda es una forma bastante fácil de escalar.</p>
<p>Con esto termino este pequeño ejemplo que no pretende nada más que mostrar las bondades de Terraccotta con un ejemplo funciona. Más adelante ya lo complicaremos.</p>
 Tagged: Java, Terracotta <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mikiorbe.wordpress.com/486/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mikiorbe.wordpress.com/486/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mikiorbe.wordpress.com/486/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mikiorbe.wordpress.com/486/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mikiorbe.wordpress.com/486/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mikiorbe.wordpress.com/486/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mikiorbe.wordpress.com/486/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mikiorbe.wordpress.com/486/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mikiorbe.wordpress.com/486/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mikiorbe.wordpress.com/486/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mikiorbe.wordpress.com&blog=3806599&post=486&subd=mikiorbe&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://mikiorbe.wordpress.com/2009/03/31/introduccion-a-terracotta-cluster-a-nivel-maquina-virtual/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e0aa1c86de99e8f09a34f5849f358bcc?s=96&amp;d=identicon&amp;r=G" medium="image">
			<media:title type="html">mikiorbe</media:title>
		</media:content>

		<media:content url="http://mikiorbe.files.wordpress.com/2009/03/terracotta_1.png?w=300" medium="image">
			<media:title type="html">terracotta_1</media:title>
		</media:content>

		<media:content url="http://mikiorbe.files.wordpress.com/2009/03/terracotta_2.png?w=300" medium="image">
			<media:title type="html">terracotta_2</media:title>
		</media:content>

		<media:content url="http://mikiorbe.files.wordpress.com/2009/03/terracotta_3.png?w=300" medium="image">
			<media:title type="html">terracotta_3</media:title>
		</media:content>
	</item>
	</channel>
</rss>
