tag:blogger.com,1999:blog-16002221018713559602024-02-19T00:32:59.381-08:00Gishac's bloggishachttp://www.blogger.com/profile/06775830448359587062noreply@blogger.comBlogger11125tag:blogger.com,1999:blog-1600222101871355960.post-12372152356514608272010-04-06T16:20:00.000-07:002010-04-06T16:21:30.656-07:00Cambio de casaEste blog ya no está activo, se fue a<br /><span style="font-size:130%;"><a href="http://gishak.wordpress.com/"><span style="font-weight: bold;">http://gishak.wordpress.com/</span></a></span>gishachttp://www.blogger.com/profile/06775830448359587062noreply@blogger.com0tag:blogger.com,1999:blog-1600222101871355960.post-82592703770961714992010-03-01T21:02:00.000-08:002010-03-02T17:56:49.058-08:00Notificar o no?... Un click menos del usuario!<span style="font-size:85%;"><span style="font-family:arial;">En todo mantenimiento ya sea una aplicación Windows o Web al momento de realizar una acción de guardar los cambios nosotros los involucra</span></span><span style="font-size:85%;"><span style="font-family:arial;">dos en el aspecto tecnológico preferimos no dar ninguna notificación y nos regocijamos haciendo el típico clear de los controles y dejándolos como si nada pasó, ya que asumimos que si no sale nada es xq todo está Ok, pero nunca falta el usuario acostumbrado a que le avisen hasta el cambio de hora, y al mismo tiempo otro usuario de la misma aplicación el cual cree que le entorpecemos su trabajo xq tiene que dar un click mas luego de habe</span></span><span style="font-size:85%;"><span style="font-family:arial;">r guardado los cambios ¬_¬<br />La solución???? Notificaciones no intrusivas :P Las cuales las vemos en aplicaciones que utilizamos a diario: En las notificaciones del outlook/thunderbird, cuando alguien comenta un post en el facebook... etc etc y si no las ves... es xq son no intrusivas xD pero cumplen su labor de informar de alguna acción o evento ocurrido dentro del sistema con el que estamos interactuando.<br />En las aplicaciones web 1.0 la manera usual de notificar al usuario era con el tipico alert("Cambios realizados con exito"); del querido amigo Javascript; despues con tantos frameworks se comenzaron a mejorar los alertbox:<br /></span></span><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://lh4.ggpht.com/_v3JKICenoks/S4yfUthBTxI/AAAAAAAAAWA/WNYGX8Rt8P4/alert2.0.jpg"><img style="cursor: pointer; width: 214px; height: 126px;" src="http://lh4.ggpht.com/_v3JKICenoks/S4yfUthBTxI/AAAAAAAAAWA/WNYGX8Rt8P4/alert2.0.jpg" alt="" border="0" /></a><br /><br /><span style="font-size:85%;">Pero aunque ahora se ven mucho mejor no eliminan la tarea de dar otro click... <span style="font-family:arial;">en ese momento entra en juego <a href="http://www.stanlemon.net/projects/jgrowl.html">jGrowl </a>un excelente añadido de jQuery</span>, el cual con una sola línea nos permite mostrar mensajes de manera simple y con muy buen estilo!<br />Descargamos el .js con sus dependencias lo agregamos a nuestra página web y lo único que tenemos que hacer para mostrar la notificacion es llamar la siguiente función js:<br /><br /><span style=";font-family:courier new;font-size:85%;"><span style="color: rgb(102, 102, 102); font-weight: bold;">$.jGrowl("Se guardaron correctamente los cambios.", { header: 'Notificación' });</span></span><br /><br />Y listo, la notificación se mostrará y se ira desvaneciendo poco a poco sin obligar al usuario a tener que realizar un paso adicional luego de realizar su tarea.<br /><br />En la siguiente imagen se observa como al guardar los cambios se muestra un mensaje informativo no instrusivo<br /><br /></span><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://lh4.ggpht.com/_v3JKICenoks/S4yiv19Y5PI/AAAAAAAAAWg/PiDmFdm0EBc/s1024/notification.jpg"><img style="cursor: pointer; width: 600px; height: 300px;" src="http://lh4.ggpht.com/_v3JKICenoks/S4yiv19Y5PI/AAAAAAAAAWg/PiDmFdm0EBc/s1024/notification.jpg" alt="" border="0" /></a><br /><span style="font-size:85%;"><br />No sólo exite jGrowl para estas tareas, tambien está el <a href="http://icebeat.bitacoras.com/mootools/growl/">MooTools Window Growl</a>, en fin... en gustos y sabores nada está dicho así que tu eliges :D<br /><br />Salu2<br /><br />gish@c<br /><br /><br /><br /></span><br /><br /><span style="font-size:85%;"><span style="font-family:arial;"><br /></span></span>gishachttp://www.blogger.com/profile/06775830448359587062noreply@blogger.com0tag:blogger.com,1999:blog-1600222101871355960.post-90842851751481184932010-02-20T18:14:00.001-08:002010-02-20T21:48:28.039-08:00Hágalo usted mismo!!!<span style=";font-family:arial;font-size:85%;" >El pan de cada día en el mundo del desarrollo de aplicaciones es encontrarnos con un problema que alguien ya solucionó... El día de hoy he sumado un punto más a la estadística ya que necesitaba generar un organigrama dinámicamente... Haciendo una búsqueda rápida en google encontre un excelente artículo en CodeProject <a href="http://www.codeproject.com/KB/cs/TreeGenerator.aspx">http://www.codeproject.com/KB/cs/TreeGenerator.aspx</a></span>. <span style="font-size:85%;"><span style="font-family:arial;"><br />Pero, como buenos consumidores siempre encontramos algo para estar inconformes, y por eso el origen de esta entrada en el blog; ya que al hechar un vistazo al artículo de cp lo primero que noté fue que a pesar de parecer muy funcional no estaba muy bonito gráficamente hablando... Y si está el código disponible... xq no añadirle un pequeño fix para que se vea como yo quiero? Muchas veces somos del grupo miro, utilizo y no toco... Como parte de la gran comunidad del "alguien ya lo hizo" no esta mal de vez en cuando ser ese que tuvo que hacerlo y lo publicó para el uso de los demás, lamentablemente algo no muy profesado en EC...<br />Yendo al grano, bastó remembrar mis andanzas por el mundo del GDI+ y darle un pequeño smooth a los cuadros del organigrama con unas cuantas líneas:<br /><br /><span style="font-family:courier new;"><span style="color: rgb(102, 102, 102);font-family:courier new;" >gr.CompositingQuality = CompositingQuality.HighQuality;</span> <span style="color: rgb(102, 102, 102);font-family:courier new;" ><br />gr.SmoothingMode = SmoothingMode.AntiAlias</span>;</span><br /><br /><span style="color: rgb(102, 102, 102);font-family:courier new;" >//Comentando lo hecho x el autor original</span> <span style="color: rgb(102, 102, 102);font-family:courier new;" ><br />//gr.DrawRectangle(boxPen, currentRectangle);</span> <span style="color: rgb(102, 102, 102);font-family:courier new;" ><br />//gr.FillRectangle(new SolidBrush(_BoxFillColor), currentRectangle);</span><br /><span style="color: rgb(102, 102, 102);font-family:courier new;" >GraphicsPath path = <span style="font-weight: bold;">CornerRendererHelper</span>.RoundRectangle(currentRectangle, 20);</span> <span style="color: rgb(102, 102, 102);font-family:courier new;" ><br />gr.FillPath(new LinearGradientBrush(currentRectangle,_BoxFillColor, _BoxFillColor2, LinearGradientMode.BackwardDiagonal), path);</span><br /><br />Aquí con la brocha gradient el organigrama se dibuja mucho mejor, y utilizando una utilería hecha por mi buen amigo <a href="http://www.facebook.com/?ref=home#%21/john.moscoso?ref=ts">John </a><span style="font-style: italic;">(seguramente ni se acuerda que hizo esa clase)</span> el rectangulo se redondea...<br /><br />He aquí las diferencias:<br /><br /><span style="font-weight: bold;">Code Project:</span><br /><br /></span></span><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.codeproject.com/KB/cs/TreeGenerator/Orgchart.jpg"><img style="cursor: pointer; width: 364px; height: 189px;" src="http://www.codeproject.com/KB/cs/TreeGenerator/Orgchart.jpg" alt="" border="0" /></a><br /><br /><span style="font-weight: bold;font-size:85%;" > <span style="font-family:arial;">Luego de las mejoras</span></span><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://lh6.ggpht.com/_v3JKICenoks/S4CfZge_inI/AAAAAAAAAS4/tOehfiQyfyQ/chart.jpg"><img style="cursor: pointer; width: 645px; height: 241px;" src="http://lh6.ggpht.com/_v3JKICenoks/S4CfZge_inI/AAAAAAAAAS4/tOehfiQyfyQ/chart.jpg" alt="" border="0" /></a><br /><br /><span style="font-size:85%;"><span style="font-family:arial;">Go ahead! Hágalo usted mismo</span></span>.<br /><br /><span style=";font-family:arial;font-size:85%;" >Los fuentes modificados de la librería se pueden <a href="http://sites.google.com/site/gishac/downloads/TreeGenerator.rar?attredirects=0&d=1">encontrar aqui</a></span><br /><br /><span style="font-size:85%;"><span style="font-family:arial;">Salu2</span></span><br /><span style=";font-family:arial;font-size:85%;" >gish@c</span><br /><br /><br /><br /><span style="font-size:85%;"><span style="font-family:arial;"><br /><br /></span></span>gishachttp://www.blogger.com/profile/06775830448359587062noreply@blogger.com0tag:blogger.com,1999:blog-1600222101871355960.post-72427470245684631332010-01-25T19:41:00.000-08:002010-01-25T20:29:43.859-08:00Cuanto sabe Google de ti?<span style="font-size:85%;"><span style="font-family:arial;">Alguna vez te has preguntado que hace google con todas las cosas que buscas???... si nadie se va a enterar que buscaste fotos de Megan Fox y le diste click a ese link vago xD ... Pues la verdad es que Google retiene muchisima información de que es lo que haces en la web (resultados de busquedas, direcciones en mapas, sitios visitados, etc etc), ya sea que tengas o no una cuenta google... Pero si tienes una cuenta google y mientras ingenuamente revisas tu gmail, se te ocurre realizar una busqueda y mas aún si estas en tu pc donde siempres estas logoneado con el tipico check de "Remember me"</span> puedes notar que al hacer la tipica busqueda en Google... estas "logoneado"</span><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjka-5do_wxVP5Ho0dTu9LDrC6NuwE0wXW7dCzKmsxNb9w0Qrf2W3qehM36UAs54MhViDuVsQjW5JX12f4hZNqab9B8YjAZWorT1qfcpq6MO8VgJKFxcHHlNnMXyjclmSkmc9CCUOQe-Ww/s1024/googsearch.PNG"><img style="cursor: pointer; width: 913px; height: 295px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjka-5do_wxVP5Ho0dTu9LDrC6NuwE0wXW7dCzKmsxNb9w0Qrf2W3qehM36UAs54MhViDuVsQjW5JX12f4hZNqab9B8YjAZWorT1qfcpq6MO8VgJKFxcHHlNnMXyjclmSkmc9CCUOQe-Ww/s1024/googsearch.PNG" alt="" border="0" /></a><br /><br /><br /><span style="font-size:85%;">Y así el monstruo de los servicios en línea tiene todo tu historial de actividades... y si aún no lo crees pues ellos mismos te ofrecen una herramienta para ver tu historial web...<br /><a href="http://www.google.com/history/?hl=en">http://www.google.com/history/?hl=en</a></span><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLBLJJlN5avOYVNSzPWR8OuoR3YByHwsj7wTHhMpBoW2TwH3Nu3n21kLjETjkasuC67Q_75WzY2tAb5Mn8JOad9JgEO-UCYDhKbknZC1CAbEeDtVgOTmSbZkMcTUyJmyUFJq0Poe0wxD4/s1024/googhistory.PNG"><img style="cursor: pointer; width: 930px; height: 434px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLBLJJlN5avOYVNSzPWR8OuoR3YByHwsj7wTHhMpBoW2TwH3Nu3n21kLjETjkasuC67Q_75WzY2tAb5Mn8JOad9JgEO-UCYDhKbknZC1CAbEeDtVgOTmSbZkMcTUyJmyUFJq0Poe0wxD4/s1024/googhistory.PNG" alt="" border="0" /></a><br /><br /><span style="font-size:85%;">Y aqui el historial de cosas que he buscado entre ayer y hoy... como se puede ver al lado izquierdo están desde la búsqueda de imagenes, blogs, las noticias (que si leo en google news), en fin... todo el track de mi vida online</span>... <span style="font-size:85%;">Preocup</span><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.googlesharing.net/images/diagram1.png"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 126px; height: 177px;" src="http://www.googlesharing.net/images/diagram1.png" alt="" border="0" /></a><span style="font-size:85%;">ado x tu privacidad??? xD les dejo <a href="http://www.googlesharing.net/index.html"><span style="font-weight: bold;">un excelente </span></a></span><span style="font-size:85%;"><a href="http://www.googlesharing.net/index.html"><span style="font-weight: bold;">add-on para el firefox (GoogleSharing)</span></a></span><span style="font-size:85%;"> que no le permite a google hacernos track ya que nos hace de proxy y nos genera una identidad anónima mientras navegamos con el firefox!!! Si algún PRO se le puede encontrar al asunto es el típico: <span style="font-style: italic;">"Alguna vez encontré en google pero no recuerdo el link..."</span> lo cual en lo personal me ha sucedido muchísimas veces y lo he encontrado en mi historial web de búsquedas xD</span><br /><span style="font-size:85%;"><br />Así que tú decides en si compartes o no tus preferencias en la web.<br /><br /><br /><br /><br /><br />Saludos,<br />gish@c</span>gishachttp://www.blogger.com/profile/06775830448359587062noreply@blogger.com0tag:blogger.com,1999:blog-1600222101871355960.post-15951881089451787262010-01-16T14:02:00.000-08:002010-01-16T16:26:16.128-08:00Edición en JTable con Db4o<span style="font-family:arial;"><span style="font-size:85%;">Una de las ventajas de una <a href="http://en.wikipedia.org/wiki/Object_database">base de datos orientada a objetos</a> como <a href="http://www.db4o.com/about/productinformation/db4o/">Db4o</a>, es la simplicidad al momento de trabajar con modelos de objetos un poco mas complejos. Este post es para mostrar como usando la flexibilidad de Java junto con Db4o (v7.4) se puede hacer un mantenimiento en un grid, al final el resultado se verá más o menos asi:<br /><br /></span></span><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSFtIcMDsbV3VidVKpXR8AvOCulnF2OAeUlmc9qFuJEO13iIKCv68mv8p5S7CEttmVe6NEKUM8Mn8RtjtElDX7u5ggsVSaB6ICGg_MLUcQKckQhs4TFSu9gQZBdsSgr5wGrjTfOP6pQPY/"><img style="cursor: pointer; width: 397px; height: 303px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSFtIcMDsbV3VidVKpXR8AvOCulnF2OAeUlmc9qFuJEO13iIKCv68mv8p5S7CEttmVe6NEKUM8Mn8RtjtElDX7u5ggsVSaB6ICGg_MLUcQKckQhs4TFSu9gQZBdsSgr5wGrjTfOP6pQPY/" alt="" border="0" /></a><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn7W_YHyxyu4d-_fv2G6k-zVNvW5umZR_nFOpiU9vBtKIA3l6lSyBCUXG3-UWB9MqC5hUQHM-skLnD57X0geFFDlL8kopvUsZZeYFOZchrzcUOR88IB5v0dgkkaw16dzm-bU0-IXBWBqk/"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 323px; height: 308px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn7W_YHyxyu4d-_fv2G6k-zVNvW5umZR_nFOpiU9vBtKIA3l6lSyBCUXG3-UWB9MqC5hUQHM-skLnD57X0geFFDlL8kopvUsZZeYFOZchrzcUOR88IB5v0dgkkaw16dzm-bU0-IXBWBqk/" alt="" border="0" /></a><span style="font-family:arial;"><span style="font-size:85%;">Como base tome las clases Car y Pilot que vienen en el tutorial de Db4o, y como se puede ver tiene un combo de seleccion de pilotos ya que es lo minimo que se requiere cuando se tiene un modelo de objetos así.<br />Lo importante aqui es sacarle el provecho al sistema de referencias de la base de datos, ya que al estar editando los objetos en el grid solo basta con hacer un update a la referencia que es esta editando para que se guarden los cambios, Las clases del proyecto se pueden ver en el gráfico a la izquierda.<br /><br /></span></span><span style="font-size:85%;"><span style="font-family:arial;">El proyecto está con Netbeans 6.5, y en el pkg <span style="font-weight: bold;">com.sample.objects</span> estan los objetos mas importantes, los del pkg <span style="font-weight: bold;">com.sample</span> son los que agrega por default el nb para proyectos java desktop.<br />Las clases DBManager, CarDB, y PilotDB son las que se encargan de las consultas y actualizaciones a la base de datos; las clases importantes en las que entraremos en mas detalle son las Model ya que son las clases que se encargan de todo detras del JTable y es donde pondremos lo necesario para persistir cualquier modificación que hagamos directo en la tabla.<br />Lo principal es comenzar con el modelo que vamos a proveer al JTable para que sepa con lo que está lidiando, asi que extendemos de AbstractTableModel, y se sobrecargan los métodos requeridos, la sobrecarga clave para el ejemplo es del método <span style="font-weight: bold;">setValueAt </span>ya que para éste caso luego de establecer el valor a la propiedad actualizamos el objeto que fue editado:<br /><br /><br /><br /><span style=";font-family:arial;font-size:78%;" ><span style="color: rgb(51, 51, 255);">public void</span> setValueAt(Object aValue, int rowIndex, int columnIndex) {<br />super.setValueAt(aValue, rowIndex, columnIndex);<br /><span style="font-weight: bold; background-color: rgb(211, 211, 211);">Car car = getDatasource().get(rowIndex); //Aqui obtenemos la instancia del objeto que está siendo editado</span><br /><span style="color: rgb(51, 51, 255);">switch </span>(columnIndex) {<br /><span style="color: rgb(51, 51, 255);">case </span>0:<br /> car.setModel(aValue.toString());<br /> break;<br /><span style="color: rgb(51, 51, 255);">case </span>1:<br /> car.setColor(aValue.toString());<br /> break;<br /><span style="color: rgb(51, 51, 255);">case </span>2:<br /> car.setPilot((Pilot) aValue);<br /> break;<br /><span style="font-weight: bold; background-color: rgb(211, 211, 211);">DBManager.getInstance().getCarDB().storeCar(car);</span><br />}</span></span></span><span></span><span style="font-size:85%;"><br /><br />Básicamente, fuera del código en Java para hacer edición en grid es el único llamado a realizar para persistir las modificaciones. Para que esto sea posible las clases model tienen una lista que utlizan como datasource<br /><span style="font-size:78%;"><br /><span style="color: rgb(51, 51, 255);">public class </span>CarTableModel extends AbstractTableModel {<br /><span style="color: rgb(51, 51, 255); font-weight: bold;">private </span><span style="font-weight: bold;">List<car> datasource;</car></span><br />.<br />.<br /><br /><br /><span style="color: rgb(51, 51, 255);">public class </span>PilotComboBoxModel extends AbstractListModel implements ComboBoxModel {<br /><span style="color: rgb(51, 51, 255);">private </span>Pilot current;<br /><span style="font-weight: bold;"><span style="color: rgb(51, 51, 255);">private </span>List<pilot> datasource;</pilot></span><br />.<br />.<br />.</span><br /><br />En la clase EditPane se encuentra</span><span style="font-size:85%;"><span style="font-family:arial;"> la carga de las listas con lo que se obtiene de la base, los objetos se mantienen en el sistema de referencias de Db4o:</span></span><br /><span style="font-size:85%;"><span style="font-family:arial;"><br /><span style="color: rgb(153, 153, 153);">//Se carga la lista de pilotos en el combo para el grid</span><br /><span style="font-size:78%;">PilotComboBoxModel cmbModel = <span style="color: rgb(51, 51, 255);">new </span>PilotComboBoxModel(<span style="color: rgb(255, 0, 0);">DBManager.getInstance().getPilotDB().getPilots()</span>);<br />cmbPilots = new JComboBox(cmbModel);<br />SetTableModel(cmbPilots);<br /><br /><span style="color: rgb(51, 51, 255);">private void </span>SetTableModel(JComboBox cmbPilots) {<br /><span style="color: rgb(153, 153, 153);">//Se carga la lista de carros a mostrar en la tabla</span><br />carTableModel = <span style="color: rgb(51, 51, 255);">new </span>CarTableModel(<span style="color: rgb(255, 0, 0);">DBManager.getInstance().getCarDB().getCars()</span>);<br /></span></span></span><span style="font-size:78%;"><span style="font-family:arial;"> <span style="color: rgb(153, 153, 153);">//Al jtable carTable le seteamos el model y el editor para la columna de pilotos</span></span><br /></span><span style="font-size:85%;"><span style="font-family:arial;"><span style="font-size:78%;"> carTable.setModel(carTableModel);<br />carTable.getColumnModel().getColumn(2).setCellEditor(<span style="color: rgb(51, 51, 255);">new </span>DefaultCellEditor(cmbPilots));<br />}</span><br /><br />El código del ejemplo se lo pueden <a href="http://sites.google.com/site/gishac/downloads/EditInTableDb4o.rar?attredirects=0&d=1">descargar aquí</a> y Db4o <a href="http://developer.db4o.com/files/folders/db4o_74/default.aspx">por aca</a>.<br /><br /><span style="font-weight: bold;">Para usar el ejemplo luego de ejecutar por primera vez el proyecto hay que comentar el llamado a la linea que llena la base de datos en la clase </span><span style="font-weight: bold;"><span style="color: rgb(51, 51, 255);">EditInTableDb4oApp</span>.<br /><br /><span style="font-size:78%;">public static void main(String[] args) {<br /><br /> <span style="color: rgb(51, 51, 255);"> DBManager.PopulateDatabase();// Comentar despues de primera ejecucion</span><br /> launch(EditInTableDb4oApp.class, args);<br />}</span><br /></span></span></span><span style="font-family:arial;"><span style="font-size:85%;"><br /></span></span><span style="font-size:85%;"><span style="font-family:arial;">En un siguiente post le agrego un par de cosas al ejemplo para cumplir con el <a href="http://es.wikipedia.org/wiki/CRUD">CRUD</a>, bueno... el Read es una busqueda que no es para el ejemplo asi que en realidad sera un CUD :P</span></span><br /><br /><span style=";font-family:arial;font-size:85%;" >Saludos,<br />gish@c</span>gishachttp://www.blogger.com/profile/06775830448359587062noreply@blogger.com0tag:blogger.com,1999:blog-1600222101871355960.post-91051326358975153082009-12-21T22:04:00.000-08:002009-12-21T22:48:15.811-08:00Being in Xmas<span style="font-size:85%;">Las típicas tradiciones de la navidad de poner los focos, el arbol, los adornos, el nacimiento, etc en las cuales nos envolvemos por la época, también deberían llegar a las cosas que utilizamos a diario (la pc :P ), por ejemplo google pone la iniciativa con sus típicos logos en la pagina de inicio...<br /><br /></span><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSywlJPf8xOZXWibO_Hx-VVIaiUY-VXC9DK6S8IgDMf-Uh1MPH4xjXYQHhFRC16Efge4fq5e60S1O7vmiwtCq-o8Tm0yCjjB94lquk9_te_YxIAAIYmFJZV2y8MfYAtXU-rKRHqSY4_Qc/s640/holidayLogos.PNG"><img style="cursor: pointer; width: 521px; height: 392px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSywlJPf8xOZXWibO_Hx-VVIaiUY-VXC9DK6S8IgDMf-Uh1MPH4xjXYQHhFRC16Efge4fq5e60S1O7vmiwtCq-o8Tm0yCjjB94lquk9_te_YxIAAIYmFJZV2y8MfYAtXU-rKRHqSY4_Qc/s640/holidayLogos.PNG" alt="" border="0" /></a><br /><span style="font-size:85%;">En mi caso decidí "tunear" el firefox con un skin navideño de tux utilizando el excelente add-in <a href="http://www.getpersonas.com/en-US/">Personas</a> para el zorro, ya que lo que mas veo durante el día es el outlook y el firefox, lamentablemente no se puede o no se como tunear el mail. Go ahead y tunea tu browser! les dejo algunos prints de skins.</span><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheS43IXQNR5KIc6Xie0Zlopu6HHE3Fm5pYjW7Qrda9VqJW7LFQGAUxKf2-_U42VdJwXgVng7WIopC0uFGsKVn-_jVfE8jSQKP-b-ypiLuNnBsxS-28OF0TwhHzDFSIwlJPGCTBdgVV8Ss/"><img style="cursor: pointer; width: 598px; height: 233px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheS43IXQNR5KIc6Xie0Zlopu6HHE3Fm5pYjW7Qrda9VqJW7LFQGAUxKf2-_U42VdJwXgVng7WIopC0uFGsKVn-_jVfE8jSQKP-b-ypiLuNnBsxS-28OF0TwhHzDFSIwlJPGCTBdgVV8Ss/" alt="" border="0" /></a><br /><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQRKpmEAj1QOD_UhLLDdtKXYSYs6OJVakGsIYkvItqg-VbuHk99JkQHWcbd0zxiXES01-XGntHXdZdzAYHOd-AMmulRgDjpCwTNue0R3uX_DF_k6T38kqhKlxW3ykNNM77E1WkrRYP5xA/"><img style="cursor: pointer; width: 626px; height: 263px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQRKpmEAj1QOD_UhLLDdtKXYSYs6OJVakGsIYkvItqg-VbuHk99JkQHWcbd0zxiXES01-XGntHXdZdzAYHOd-AMmulRgDjpCwTNue0R3uX_DF_k6T38kqhKlxW3ykNNM77E1WkrRYP5xA/" alt="" border="0" /></a><br /><br /><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSxdG7p5KpH6jxguAJA1-6R70USIduUQZbtNh3rFzeLUlXh0kdsXe2hElH0EpLig9XwROWf_qcivzW9xQmZRz9YgA06kihM9UBgUM7sawgRuKONmHiyO-cO9a-eUOcEdpGXXVVHeuqIeM/"><img style="cursor: pointer; width: 626px; height: 267px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSxdG7p5KpH6jxguAJA1-6R70USIduUQZbtNh3rFzeLUlXh0kdsXe2hElH0EpLig9XwROWf_qcivzW9xQmZRz9YgA06kihM9UBgUM7sawgRuKONmHiyO-cO9a-eUOcEdpGXXVVHeuqIeM/" alt="" border="0" /></a><br /><br /><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJWzguGWa0PehrthyF_v5dT3KCBd-NC70zDWr-MjKOrIiac53q_my64LlRQ_4fTjSdybFNbyEphOXio6I9hTr0NKih8nco7Z9KeZ6FVS9XnsKzJBMMiXOTt_T0KLXZQXCakdY1aRcuLIM/"><img style="cursor: pointer; width: 651px; height: 276px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJWzguGWa0PehrthyF_v5dT3KCBd-NC70zDWr-MjKOrIiac53q_my64LlRQ_4fTjSdybFNbyEphOXio6I9hTr0NKih8nco7Z9KeZ6FVS9XnsKzJBMMiXOTt_T0KLXZQXCakdY1aRcuLIM/" alt="" border="0" /></a>gishachttp://www.blogger.com/profile/06775830448359587062noreply@blogger.com0tag:blogger.com,1999:blog-1600222101871355960.post-79418753999172550432009-12-13T16:28:00.000-08:002009-12-13T16:40:08.306-08:00Musik Flashback<span style="font-size:85%;">Como un día cualquiera en mi laptop, me encontraba escuchando musik con el winamp :D y salió Wait de White Lion, me entró la curiosidad después de escuchar el solo de guitarra ya que es bastante rápido, ritmico, en resumen excelente!!! Navegué un rato por el tubo y les comparto uno de los mejores que encontré!!! Quizás habría que recomendar un curso de guitarra a los jonas brothers, tokio hotel y demás grupillos rockeros noveleros que a duras penas entonan los acordes en una guitarra eléctrica... o si estoy equivocado por favor que alguien me postee un solo de guitarra de alguna canción actual que le haga mover los dedos simulando una guitarra al más incauto que escuche canciones de white lion, rata blanca, ozzy, etc etc etc etc :D<br />Disfruten el solo.</span><br /><br /><br /><object height="344" width="425"><param name="movie" value="http://www.youtube.com/v/Xx3781UdQfk&hl=en_US&fs=1&"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://www.youtube.com/v/Xx3781UdQfk&hl=en_US&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="344" width="425"></embed></object>gishachttp://www.blogger.com/profile/06775830448359587062noreply@blogger.com1tag:blogger.com,1999:blog-1600222101871355960.post-52243658707809523172009-12-07T21:02:00.000-08:002009-12-07T21:28:49.203-08:00Google Wave en Mantenimiento<span style="font-size:85%;">Entrando como de costumbre al wave me encontre con la novedad de que estaba abajo por mantenimiento... lo cual es normal ya que estan apenas en preview, pero me pareció graciosa la imagen del "down for maintenance", se las dejo por si no tienen la oportunidad de encontrarse con la imagen (Al menos tiene mucho mas sentido que la imagen cuando se cae el twitter)</span><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1olOECVJ3yy-VOVllKFxZ4uovMvjL7glsMrRGNuBPNrY7XTL98GORlLTtmTIBKSGxbOcnE4LYvHnBsEn1sfePtrj46xq64KJ9E1XEW03kPU58oHWrd-4aViHvANptfpckNnYfLRT7_1I/s1024/wave%20out.PNG"><img style="cursor: pointer; width: 886px; height: 434px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1olOECVJ3yy-VOVllKFxZ4uovMvjL7glsMrRGNuBPNrY7XTL98GORlLTtmTIBKSGxbOcnE4LYvHnBsEn1sfePtrj46xq64KJ9E1XEW03kPU58oHWrd-4aViHvANptfpckNnYfLRT7_1I/s1024/wave%20out.PNG" alt="" border="0" /></a><br /><span style="font-size:85%;"><br /><br />Y aqui la imagen del twitter...</span><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIDOMHaroc238Mq3i1xP3LXqK0qF-UJScXc5jjKwVe5NIfNUomRzxB9nZTrigGH6jhvZgAd6UKYgpJy20GMlovoNFsVkS1WWghAQM0Hv59yVm5va-pG7nrXPM-PwhNEZ6ahppl5n47wOM/s576/twitter2.jpg"><img style="cursor: pointer; width: 457px; height: 378px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIDOMHaroc238Mq3i1xP3LXqK0qF-UJScXc5jjKwVe5NIfNUomRzxB9nZTrigGH6jhvZgAd6UKYgpJy20GMlovoNFsVkS1WWghAQM0Hv59yVm5va-pG7nrXPM-PwhNEZ6ahppl5n47wOM/s576/twitter2.jpg" alt="" border="0" /></a>gishachttp://www.blogger.com/profile/06775830448359587062noreply@blogger.com0tag:blogger.com,1999:blog-1600222101871355960.post-69464513793477606882009-11-25T22:02:00.000-08:002009-11-27T20:34:48.529-08:00Google Search Web Client con Google's Go<span style="font-size:85%;">Luego de haber danhado el ubuntu (al setear mal el environment del root y otros danhos colaterales); y tener ciertos problemas para compilar los fuentes de GO, como resultado de estos dias de aprendizaje publico este post con un ejemplo de un web server que hace una busqueda simple en google a traves de GO! y </span><span style="font-size:85%;"><a href="http://code.google.com/apis/ajaxsearch/">Google Ajax Search</a></span><br /><span style="font-size:85%;">Voy a asumir que ya se tiene un linux con GO compilado y listo para funcionar; las instrucciones de instalacion se pueden seguir en <a href="http://golang.org/doc/install.html">este link</a>.<br /><br />Bueno ahora si empezamos a escribir el codigo:<br />Vamos a tener los siguientes archivos Go:<br />google_go_search.go - El web server<br />search_handler.go - El manejador de requests de busqueda<br />page_templates.go - El render del html<br /><br /><br />******************************page_templates.go************************************************* <span style="color: rgb(51, 51, 153);font-size:78%;" ><br /></span></span><span style="font-size:85%;">En este archivo vamos a tener la logica para hacer render de la pagina de inicio y la pagina de resultados de las busquedas<a href="http://code.google.com/apis/ajaxsearch/"></a>, por ahora vamos a hacer algo basico para probar que la plantilla funcione, asi que vamos a crear una funcion con el render html que simplemente va a generar un boton con un alert (El html tiene un * para poder mostrarlo aqui en el post):<br /><br /></span><span style="font-size:85%;"><span style="color: rgb(51, 51, 153);font-size:78%;" >package templates<br />import(<br />"os";<br />)<br /><br />func RenderHome()(htmlTemplate string, err os.Error)<br />{<br />htmlTemplate=`<br /><*html><br /><*head><br /><*title>Gishac's Google Search with GO!<*/title><br /><*script language="javascript"><br />function doSearch(){<br />alert("Google's go search rocks");<br />}<br /><*/script><br /><*/head><br /><*body><br /><*div style="width:100%"><br /><*div align="center"><br /><*span> Google Go's Search!!! </span></span><span style="color: rgb(51, 51, 153);font-size:78%;" > <*input value="Search with Go!" id="search" onclick="doSearch();" type="button"><br /><*/div><br /><*/div><br /><*body><*/html><br />`;<br />return;<br />}</span> <span style="font-size:85%;"><br />***************************************************************************************<br /><br />Aqui por ahora no tenemos ninguna logica especial, simplemente una funcion que retorna una plantilla html, por lo cual no entrare en detalle con este archivo.</span><br /><br /><span style="font-size:85%;">Vamos a crear el web server para hacer render de nuestra pagina de inicio, a un costado de cada linea esta su explicacion:<br /><span style="color: rgb(102, 102, 102);font-size:78%;" ><br /></span></span><span style="font-size:85%;">******************************google_go_search.go***********************************************</span><br /><span style="font-size:85%;"><span style="color: rgb(102, 102, 102);font-size:78%;" ><br /><span style="color: rgb(51, 51, 153);">package main</span> <span style="color: rgb(51, 51, 153);"><br />import(</span> <span style="color: rgb(51, 51, 153);"><br />"./page_templates"; </span><span style="font-weight: bold; color: rgb(51, 51, 153);">//Este es el nombre el archivo de templates que importamos</span><br /><span style="color: rgb(51, 51, 153);"> "flag";</span> <span style="color: rgb(51, 51, 153);"><br />"http";</span><br /><span style="color: rgb(51, 51, 153);"> "io";</span><br /><span style="color: rgb(51, 51, 153);"> "strconv";</span><br /><span style="color: rgb(51, 51, 153);"> "log";</span><span style="font-weight: bold; color: rgb(51, 51, 153);"> // Imports de librerias nativa de Go</span><br /><span style="color: rgb(51, 51, 153);">)</span><br /><span style="color: rgb(51, 51, 153);">var port = flag.Int("port",8087,"Puerto donde se ejecuta el web server") </span><span style="font-weight: bold; color: rgb(51, 51, 153);">//Definimos el flag con el numero de puerto para el server</span> <span style="color: rgb(51, 51, 153);"><br /><br />func main()<br />{</span><br /><span style="color: rgb(51, 51, 153);"> http.Handle("/",http.HandlerFunc(HandleHomePage)); </span><span style="font-weight: bold; color: rgb(51, 51, 153);">//Inicializamos el servidor web y le pasamos una funcion que atiene el request http para la pagina de inicio /</span><br /><span style="color: rgb(51, 51, 153);"> log.Stdoutf("Iniciando el web server: http://localhost:%d\nPara detener el servidor presioar Ctrl+C\n", *port);</span> <span style="color: rgb(51, 51, 153);"><br />err := http.ListenAndServe(":"+strconv.Itoa(*port), nil);</span><span style="font-weight: bold; color: rgb(51, 51, 153);"> //Se levanta el servidor web</span><br /><span style="color: rgb(51, 51, 153);">if err != nil {</span> <span style="color: rgb(51, 51, 153);"> panic("Error: %s\n", err.String())</span> <span style="color: rgb(51, 51, 153);"> }</span><br /><span style="color: rgb(51, 51, 153);">log.Stdout("Fin de sesion web"); </span> <span style="color: rgb(51, 51, 153);">}</span> <span style="font-weight: bold;"><br /><br /></span><span style="font-weight: bold; color: rgb(51, 51, 153);">//Funcion que atiende el request http en /</span><br /><span style="color: rgb(51, 51, 153);">func HandleHomePage(c *http.Conn, req *http.Request)<br />{</span><br /><span style="color: rgb(51, 51, 153);"> homePageTemplate, err := templates.RenderHome();</span><span style="font-weight: bold; color: rgb(51, 51, 153);"> // Aqui llamamos a la funcion que creamos en el package templates</span><br /><span style="color: rgb(51, 51, 153);"> if err != nil {</span> <span style="color: rgb(51, 51, 153);"> panic("Error al hacer render: " + err.String())</span> <span style="color: rgb(51, 51, 153);"> }</span><br /><span style="color: rgb(51, 51, 153);"> io.WriteString(c, homePageTemplate);</span><span style="font-weight: bold; color: rgb(51, 51, 153);"> //Hacemos render del html que nos devuelve el metodo</span><br /><span style="color: rgb(51, 51, 153);">}</span></span> </span><br /><span style="font-size:85%;"><br />********************************************************************************************<br />En esta instancia ya podemos compilar nuestros archivos y mandar a ejecutar el web server!!! :D</span><br /><span style="font-size:85%;">Para compilar y ejecutar el programa escribimos los siguientes comandos con el siguiente resultado:<br /><br /></span><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiG2CzQqE7CRPAed0Ua0tfBdE2XDY2JKCW6WhLL_eVrfmThp1Dile3RcycVdllEJXbfctmeyAlFyNM1BJRmi473s9ZUuMFVTGiYucTIVm5Gdu-3ZI6FAWxsIkW064PKCkAXB28hEguyyqM/"><img style="cursor: pointer; width: 480px; height: 185px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiG2CzQqE7CRPAed0Ua0tfBdE2XDY2JKCW6WhLL_eVrfmThp1Dile3RcycVdllEJXbfctmeyAlFyNM1BJRmi473s9ZUuMFVTGiYucTIVm5Gdu-3ZI6FAWxsIkW064PKCkAXB28hEguyyqM/" alt="" border="0" /></a><br /><br /><span style="font-size:85%;">Listo, podemos probar nuestro web server y la funcionalidad de la plantilla html que escribimos!</span><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvQY2KjidRuAB5sDffm1Xw2KpV3s950_X1AVfL08WZNYUUVblxHc_P8YtZ7Dz-fElRltfarId84Ge9LwxUTEDeS-axxFajZGLl2encZSp9Nf7GJGFuWtbJhVJGnUulBKi4d4j61RX7f5w/s800/go_rocks.png"><img style="cursor: pointer; width: 800px; height: 500px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvQY2KjidRuAB5sDffm1Xw2KpV3s950_X1AVfL08WZNYUUVblxHc_P8YtZ7Dz-fElRltfarId84Ge9LwxUTEDeS-axxFajZGLl2encZSp9Nf7GJGFuWtbJhVJGnUulBKi4d4j61RX7f5w/s800/go_rocks.png" alt="" border="0" /></a><br /><br /><span style="font-size:85%;">Hasta ahora todo es felicidad xD asi que vamos a modificar la plantilla para colocar un textbox donde vamos a escribir la busqueda que haremos en google desde la aplicacion, y ademas definir el metodo post y el action que luego vamos a controlar desde el codigo del web server.<br /><br />****************************page_templates.go************************<br /><span style="color: rgb(0, 0, 153);font-size:78%;" >.<br />.<br />.<br />func RenderHome()(htmlTemplate string, err os.Error)<br />{<br />htmlTemplate=`<br /><*title>Gishac's Google Search with GO!<br /><*form method="POST" action="/search"><span style="font-weight: bold;"> //Definimos el post que va a ser manejado en /search</span><br /><*div style="width: 100%;"><br /><*div align="center"><br /><*span style="margin-top: 15px;" > Google Go's Search!!! </span></span><span style="color: rgb(0, 0, 153);font-size:78%;" ><br /><*table><br /><*tbody><br /><*td><br /><*input id="search_box" name="search_box" style="width: 300px;" type="text"><br /><*/td><br /><*td><br /><*input value="Search with Go!" id="search" type="submit"> <span style="font-weight: bold;">//El boton ahora es un submit</span><br /><*/td><br /><*/tr><br /><*/tbody><br /><*/div><br /><*/div><br /><*/form></span><span style="font-size:85%;"><span style="color: rgb(0, 0, 153);font-size:78%;" ><br /><br />`;<br />return;<br />}</span><br />*********************************************************************************************<br /><br />Con esto tenemos la pagina de busqueda lista para hacer su request:<br /><br /></span><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQHk9U3EC9Y4axiv8VxgfP1MIhW7eTSPoJEK3-E354vdb32jFNR_Yqoux4tB4Qm2kfpDn-hdokW8cf3EzYa0ZMSY0cElI0qwTc1QgR3PUqobh_AkQekoeT70vELr8fxht42z5wTU3kjJ0/"><img style="cursor: pointer; width: 674px; height: 277px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQHk9U3EC9Y4axiv8VxgfP1MIhW7eTSPoJEK3-E354vdb32jFNR_Yqoux4tB4Qm2kfpDn-hdokW8cf3EzYa0ZMSY0cElI0qwTc1QgR3PUqobh_AkQekoeT70vELr8fxht42z5wTU3kjJ0/" alt="" border="0" /></a><br /><br /><br /><span style="font-size:85%;">Ahora viene le parte donde captamos el request de busqueda, hacemos un request http al servicio de google ajax search, que nos devuelve un string en formato json que lo podemos "parsear" con el api de json de google's go.<br />Para captar el request agregamos otro handler http al web server</span><br /><br /><span style="font-size:85%;">******************************google_go_search.go***********************************************<br /><span style="color: rgb(51, 51, 153);font-size:78%;" >http.Handle("/search",http.HandlerFunc(HandleSearchResult));<span style="font-weight: bold;"> //funcion delegada a manejar el request<br />.<br />.<br /><br /></span><span style="font-weight: bold;">//Funcion que maneja request en la pagina de busqueda /search</span><br />func HandleSearchResult(c *http.Conn, req *http.Request){<br />req.ParseForm();<br />searchText := req.FormValue("search_box");<br />log.Stdoutf("Texto a buscar:%s\n", searchText);<br />searchResults, err:= searchHandler.GoogleSearch(searchText);<span style="font-weight: bold;"> //Hacemos la busqueda del texto ingresado</span><br />if err != nil {<br /> panic("Error al hacer busqueda: " + err.String())<br />}<br />searchResultsPageTemplate, err := templates.RenderSearchResult(searchResults); <span style="font-weight: bold;">//Llamamos al metodo que hace el render de los resultados</span><br />io.WriteString(c, searchResultsPageTemplate);<br />}</span><br />*******************************************************************************************<br /><br />La parte mas importante del ejemplo el http get de la busqueda y el parse json de los resultados obtenidos.<br /><br />**************************************search_handler.go***********************************<br />Primero definimos una estructura que respresenta el item json con cada respuesta de la busqueda, el formato de la respuesta del api de google es el siguiente:<br /><br /><span style="font-size:78%;">{"responseData": {"results":[{"<span style="font-weight: bold;">GsearchResultClass</span>":"GwebSearch","<span style="font-weight: bold;">unescapedUrl</span>":"http://code.google.com/","<span style="font-weight: bold;">url</span>":"http://code.google.com/u/gishac/","<span style="font-weight: bold;">visibleUrl</span>":"code.google.com","<span style="font-weight: bold;">cacheUrl</span>":"http://www.google.com/search","<span style="font-weight: bold;">title</span>":"my title","<span style="font-weight: bold;">titleNoFormatting</span>":"title 2","<span style="font-weight: bold;">content</span>":"xyz"}</span><br /><br />Por lo tanto tenemos que definir una estructura de similares caracteristicas ya que el api de json de go's se maneja a traves de indices clave/valor.<br /><br /><span style="color: rgb(51, 51, 153);font-size:78%;" >type GoogleSearchResult struct{<br />GsearchResultClass string;<br />unescapedUrl string;<br />url string;<br />visibleUrl string;<br />cacheUrl string;<br />title string;<br />titleNoFormatting string;<br />content string;<br />}</span><br /><br />Ahora un vistazo al codigo que hace el request y llena las estructuras<br /><br /><span style="color: rgb(51, 51, 153);font-size:78%;" >//Funcion de busqueda<br />func GoogleSearch(searchText string)(searchResult string, err os.Error)<br />{<br />searchResult="Google search done";<br />var finalURL = "";<br />req := new(http.Request);<span style="font-weight: bold;"> //Creamos estructura httpRequest</span><br />req.URL, err = http.ParseURL("http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=" + http.URLEscape(searchText)); <span style="font-weight: bold;">//Url para hacer el request de busqueda</span><br />if err != nil {<br /> log.Stdout("Error parse URL" + err.String());<br /> return "", err<br />}<br /> resp := new(http.Response); <span style="font-weight: bold;">//Creamos estructura para obtener la respuesta</span><br />log.Stdout("Request " + req.URL.String());<br />resp,finalURL,err = http.Get(req.URL.String()); <span style="font-weight: bold;">//Hacemos el get</span><br />if err != nil {<br /> log.Stdout("Error send request" + err.String() + finalURL);<br /> return "", err<br />}<br />var rawSearchResult = "";<br />rawSearchResult = getResponseBody(resp); <span style="font-weight: bold;">//Obtenemos la respuesta en formato string</span><br />jsonResult, err := parseJson(rawSearchResult); <span style="font-weight: bold;">//Hacemos el parse para tener la respuesta en estructuras json</span><br /><br />var i int;<br />var data json.Json;<br />data = jsonResult.Get("responseData").Get("results"); <span style="font-weight: bold;">//De la estructura json sacamos el arreglo con los resultados de la busqueda</span><br />var objectArray []GoogleSearchResult; <span style="font-weight: bold;">//Creamos un arreglo dcon el tipo de estructura definido para almacenar los resultados de busqueda</span><br />objectArray = make([]GoogleSearchResult, data.Len()); <span style="font-weight: bold;">//Hacemos el allocate para el arreglo </span><br />for i = 0; i < style="font-weight: bold;">//Recorremos todos los resultados de la busqueda para ir creando cada estructura</span><br /> <span style="color: rgb(51, 51, 153);font-size:78%;" >var elem = data.Elem(i); <br /> objectArray[i] = *parseSearchResults(elem);<br />}<br />searchResult =renderResultHTML(objectArray); </span><span style="font-weight: bold; color: rgb(51, 51, 153);font-size:78%;" >//Armamos el html con los resultados de la busqueda</span><span style="color: rgb(51, 51, 153);font-size:78%;" ><br />return;<br />}</span></span><br /><br /><span style="color: rgb(51, 51, 153);font-size:78%;" ><span style="font-weight: bold;">//Funcion para hacer parse de elemento jSon a estructura GoogleSearhResult</span><br />func parseSearchResults(elem json.Json)*GoogleSearchResult{<br /> itemResult := new(GoogleSearchResult);<br />itemResult.GsearchResultClass = elem.Get("GsearchResultClass").String();<br />itemResult.unescapedUrl = elem.Get("unescapedUrl").String();<br />itemResult.url = elem.Get("url").String();<br />.<br />.<br />.<br />return itemResult;<br />}<br /><br /><span style="font-weight: bold;">//Funcion para generar el html de salida</span><br />func renderResultHTML(searchResults []GoogleSearchResult) string{<br /> var i int;<br /> var html = `<*div style="'width:100%;heigth:100%'"><*table>`;<br /> for i = 0; i < html="html+`<*tr" style="padding-top:10px"><*td style="padding-top:10px;border-bottom:1px solid #336699"><*span>` + searchResults[i].title +`<*/span><*br/><*a target="_blank" href="` + searchResults[i].url + `">` + searchResults[i].url + `**<br />`;<br /> html=html+ `<*span>`+ searchResults[i].content +`<*/span><*br /><*/td><*/tr>`;<br /> }<br /> html=html+`<*/table><*/div>`;<br /> return html;<br />}</span><span style="font-size:85%;"><span style="color: rgb(51, 51, 153);font-size:78%;" ><br /></span><br />Con esto ya podemos probar la aplicacion de busqueda y nos muestra el siguiente resultado<br /><br /></span><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxI7pkQsY2bDZRGTM_SmvL8b-LMxQQRPJ-G81bQaRmRALWzsf4_gYaqyM8NkceWaEdIf-aU0xFCdp3F27U3VqSDibxHqDAdbU1DJC43fEqh46APy4yhOMZI-1PX-nYVaQqSD-oHFXURi0/"><img style="cursor: pointer; width: 624px; height: 257px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxI7pkQsY2bDZRGTM_SmvL8b-LMxQQRPJ-G81bQaRmRALWzsf4_gYaqyM8NkceWaEdIf-aU0xFCdp3F27U3VqSDibxHqDAdbU1DJC43fEqh46APy4yhOMZI-1PX-nYVaQqSD-oHFXURi0/" alt="" border="0" /></a><br /><span style="font-size:85%;"><br /></span><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-1StQW9ZWrqluNGAa_Hsq6g003mujG6b_KdQYguSgGronbp4DOyXUpadJuRPOMPDn24AMrzf5BoiIxUBEQtdADJRkUB5dfoVCpkfhOdOmeQvS9v6JSlT2DgT_MHbIZ-VZox7AAenpQfM/s800/go_search_result.png"><img style="cursor: pointer; width: 665px; height: 392px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-1StQW9ZWrqluNGAa_Hsq6g003mujG6b_KdQYguSgGronbp4DOyXUpadJuRPOMPDn24AMrzf5BoiIxUBEQtdADJRkUB5dfoVCpkfhOdOmeQvS9v6JSlT2DgT_MHbIZ-VZox7AAenpQfM/s800/go_search_result.png" alt="" border="0" /></a><br /><br /><span style="font-size:85%;">Con eso queda en evidencia que para ser un lenguaje experimental tiene muchisima funcionalidad (aun no he probado las goroutines), al principio hay que acostumbrarse un poco a la sintaxis y a la ideologia que trata de transmitir go, pero termina siendo agradable y rapido.<br /><br />Se pueden descargar los fuentes en el siguiente link.<br /><a href="http://sites.google.com/site/gishac/downloads/google_go_search_files.zip?attredirects=0">http://sites.google.com/site/gishac/downloads/google_go_search_files.zip?attredirects=0</a></span><br /><br /><span style="font-weight: bold;font-size:85%;" >gish@c</span>gishachttp://www.blogger.com/profile/06775830448359587062noreply@blogger.com0tag:blogger.com,1999:blog-1600222101871355960.post-5997809257218477802009-11-20T23:33:00.000-08:002009-11-28T08:54:08.746-08:00Scala & Lift Web Framework<span style=";font-family:arial;font-size:85%;" >Bueno despues de casi un año de haber abierto el blog he decidido crear un primer articulo y lo voy a basar en crear un pequeno proyecto en Scala+Lift y luego migrarlo a Ec</span><span style=";font-family:arial;font-size:85%;" >lipse Galileo (Voy a comer las ñ(nh), tildes, etc ya que este teclado en Ubuntu no me funca el Alt izq jeje).<br />Para empezar hay que que tener el JDK de Sun</span><span style="font-size:85%;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6TflG8rSB4QpbvVC-Llx39d9KeFwDrUpck124Cf0YgfIgH08DJBokO80hJQk5BflvS4njKW7aikOjWw1xrIKr3rGetgtBIlbqOIqPra4PTDzwktZqL5nq4R-l9wsUxudrziufLjBVSG4/s1600/javaVersion"><img style="cursor: pointer; width: 380px; height: 94px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6TflG8rSB4QpbvVC-Llx39d9KeFwDrUpck124Cf0YgfIgH08DJBokO80hJQk5BflvS4njKW7aikOjWw1xrIKr3rGetgtBIlbqOIqPra4PTDzwktZqL5nq4R-l9wsUxudrziufLjBVSG4/s400/javaVersion" alt="" id="BLOGGER_PHOTO_ID_5406460403273150002" border="0" /></a><br /></span><span style="font-size:85%;"><br /><a href="http://www.eclipse.org/downloads/">Eclipse Galileo</a> y el plugin de <a href="http://www.scala-lang.org/node/94">Scala IDE</a>.<br />Despues de googlear un poco sobre proyectos web con Scala encontre muy buenas referencias sobre <a href="http://liftweb.net/index.html">Lift WebFramework</a> para intregrarlo en el proyecto (Xq sera que ese background me recuerda a Twitter??? xD )<br /></span><span style="font-size:85%;">Como vamos a crear el esqueleto del proyecto de manera independiente vamos a hacerlo desde <a href="http://maven.apache.org/download.html">Maven.</a><br />Luego de bajar y descomprimir el tar.gz de Maven hay que configurar un par de variables de ambiente asi que nos vamos a modificar el profile de nuestro usuario:<br /></span><span style="font-size:85%;"><br />Respaldamos el profile</span><span style="font-size:85%;"><br /></span><span style="font-size:85%;"><span style="font-style: italic; background-color: rgb(211, 211, 211);">gishac@gishac-ubuntu:/etc$ sudo cp profile profile_b</span></span><span style="font-size:85%;"><span style="font-style: italic; background-color: rgb(211, 211, 211);">ackup</span><br /><br /><span style="font-size:85%;"><span>Agregamos un par de variables de ambiente que necesita Maven al profile<br /></span>Para editar el profile<span style="font-style: italic;"><br /></span></span><div style="text-align: center;"><div style="text-align: left;"><span style="font-size:85%;"><span style="font-style: italic; background-color: rgb(211, 211, 211);"> gishac@gishac-ubuntu:/etc$ sudo gedit profile<br /></span></span><br /></div></div><span style="font-size:85%;">Colocamos la siguiente linea (en mi caso puse la r</span></span><span style="font-size:85%;"><span style="font-size:85%;">uta de instalacion del jdk) al final del archivo</span><br /></span><span style="font-size:85%;"><span style="font-size:85%;"><span style="font-style: italic; background-color: rgb(211, 211, 211);">JAVA_HOME=/usr/lib/jvm/java-6-sun-1.6.0.15 export JAVA_HOME</span><span style="font-style: italic; background-color: rgb(211, 211, 211);"><br /></span><br /></span></span><span style="font-size:85%;"><span style="font-size:85%;">Colocamos las siguientes lineas</span></span><span style="font-size:85%;"> donde se define el home del Maven al final del archivo (esta es la ruta donde descomprimimos el tar de Maven, en mi caso) y modificamos la variable PATH<br /></span><span style="font-size:85%;"><span style="background-color: rgb(211, 211, 211);"><br />M2_HOME=/home/gishac/program_files/apache-maven-2.2.1 export M2_HOME<br />PATH=$PATH:$JAVA_HOME/bin:$M2_HOME/bin<br /><br /></span><br />Despues de editar el profile reiciamos... (Windows style)<br /><br /></span><span style="font-size:85%;">Ahora si podemos verificar si todo esta OK<br /><br /></span><span style="font-size:85%;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZJTfQXi78sFi50zF0CW0mU6H3kNm97szZ05xIUCrO0jM0G9L0qB_fzY8iCdMN4mToTBxKP6HoR09mODwCa8yVnL4xGQvBnJI5XQpsremaq5KoNh0CCgmLxrhEiVO30UIPGYlRRCzNC1g/s1600/mavenCheck.png"><img style="cursor: pointer; width: 400px; height: 154px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZJTfQXi78sFi50zF0CW0mU6H3kNm97szZ05xIUCrO0jM0G9L0qB_fzY8iCdMN4mToTBxKP6HoR09mODwCa8yVnL4xGQvBnJI5XQpsremaq5KoNh0CCgmLxrhEiVO30UIPGYlRRCzNC1g/s400/mavenCheck.png" alt="" id="BLOGGER_PHOTO_ID_5406477541314491906" border="0" /></a><br /><br /></span><span style="font-size:85%;">Ahora si ya tenemos todo listo para crear el proyecto, comenzamos con la estructura del proyecto Lift desde maven </span><span style="font-size:85%;">con los siguientes comandos:<br /></span><p class="noindent"><span style="font-size:85%;"><span class="pcrr8t-x-x-109" style="background-color: rgb(211, 211, 211);">mvn archetype:generate-U</span></span></p><p class="noindent"><span style="font-size:85%;">Nos muestra la lista de archetypes y escogemos el 32<br /></span></p><p class="noindent"><span style="font-size:85%;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJW1caEsEwHmwUTOQdpHhkj3TrD-mH2hyphenhyphenvsCekzL8qvf5J2NccysKrB8xTULyPg-Kf4xinHFLbZXBbwC9otRyIoQKEUEpPC5C-aOASByXDwNLUnbOn3fdH3SNAwD1_NNnzRnVSaBFNju4/s1024/step1.png"><img style="cursor: pointer; width: 794px; height: 312px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJW1caEsEwHmwUTOQdpHhkj3TrD-mH2hyphenhyphenvsCekzL8qvf5J2NccysKrB8xTULyPg-Kf4xinHFLbZXBbwC9otRyIoQKEUEpPC5C-aOASByXDwNLUnbOn3fdH3SNAwD1_NNnzRnVSaBFNju4/s1024/step1.png" alt="" border="0" /></a></span></p><p class="noindent"><span style="font-size:85%;">Aqui llenamos algunos valores que nos pide para el archetype lift: groupId, artifactId, version(en blanco), y el package:</span></p><p class="noindent"><span style="font-size:85%;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHicyF8fK_MUjrbcE9MhgTN_EQBzO-R585CvnKz6ugr3EUlrI8sjMybRqfItKE3JydxI2XP5Q2-Qm-X27q4imwogdl3T3HsDBTO8iqiwAJjKdj1hIkYVqRRjcdO2p0BcDvjseMklyich4/"><img style="cursor: pointer; width: 817px; height: 345px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHicyF8fK_MUjrbcE9MhgTN_EQBzO-R585CvnKz6ugr3EUlrI8sjMybRqfItKE3JydxI2XP5Q2-Qm-X27q4imwogdl3T3HsDBTO8iqiwAJjKdj1hIkYVqRRjcdO2p0BcDvjseMklyich4/" alt="" border="0" /></a></span></p><p class="noindent"><span style="font-size:85%;">Luego de confirmar con Y obtenemos el resultado de crear el esqueleto del proyecto<br /></span></p><p class="noindent"><span style="font-size:85%;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNAynIWdl2aHmADEPX-uhzrvfO6yaH7TxTysasI0UIIVLSTDVWihZRiV1QgqKO-PaQ_Ve3WLPlnUdLFtouAsg9ObulByz5G3vRKsaw2DdK7BX1PpriQu94MEJu7Nqu3D8IgH3NOzJQFGs/"><img style="cursor: pointer; width: 814px; height: 343px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNAynIWdl2aHmADEPX-uhzrvfO6yaH7TxTysasI0UIIVLSTDVWihZRiV1QgqKO-PaQ_Ve3WLPlnUdLFtouAsg9ObulByz5G3vRKsaw2DdK7BX1PpriQu94MEJu7Nqu3D8IgH3NOzJQFGs/" alt="" border="0" /></a></span></p><p class="noindent"><span style="font-size:85%;">Para darle un check a nuestro proyecto levantamos el web server, primero nos ubicamos en el directorio donde se nos genero el proyecto y luego desde el maven iniciamos el jetty:</span></p><p class="noindent"><span style="background-color: rgb(211, 211, 211);font-size:85%;" >cd scalademo<span class="pcrr8t-x-x-109" style="background-color: rgb(211, 211, 211);font-size:85%;" ><br />mvn jetty:run</span></span></p><p class="noindent"><span style="font-size:85%;">Ahora si ya tenemos levantada nuestra web app :D<br /></span></p><p class="noindent"><span style="font-size:85%;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3zUDazwGS-Bi4DDoDPKP-naHNjCILYDK-0dQnnNbKA7ENkgQGc9mNT5JlzTMDeo4kaZhryfnJy8xpqZNOrzXEeU74bdYzsqMYehZJC2s_4GGgU3Kmvws4jC5qx0C-AkhNz_mJbO5hXx8/s800/webapp.png"><img style="cursor: pointer; width: 663px; height: 391px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3zUDazwGS-Bi4DDoDPKP-naHNjCILYDK-0dQnnNbKA7ENkgQGc9mNT5JlzTMDeo4kaZhryfnJy8xpqZNOrzXEeU74bdYzsqMYehZJC2s_4GGgU3Kmvws4jC5qx0C-AkhNz_mJbO5hXx8/s800/webapp.png" alt="" border="0" /></a></span></p><p class="noindent"><span style="font-size:85%;">Para facilitarnos la edicion importamos el proyecto en Eclipse como un proyecto Maven, se debe tener instalado un plugin de Maven<br /></span></p><p class="noindent"><span style="font-size:85%;"><a href="http://m2eclipse.sonatype.org/">http://m2eclipse.sonatype.org/</a></span></p><p class="noindent"><span style="font-size:85%;">Una vez importado el proyecto creamos las configuraciones de Run y Stop basado en Maven.</span></p><p class="noindent"><span style="font-size:85%;">Click derecho sobre el proyecto-> Run As -> Run Configurations<br />Sobre la opcion de Maven Build creamos 2 nuevas configuraciones:</span></p><p class="noindent"><span style="font-size:85%;">Jetty Start</span></p><p class="noindent"><span style="font-size:85%;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_oGZVDBtb6Hxhz3uEDN-0uHVFeg5dEo-IiKsJSqDTeKiXDVZCkmUlqoYIDe26v5Y-_2KMRNvOOkFE5Ohd1gG_d4OALfLSUpgPqat8a-SKTckqv6JiTDGDJw-Yc_7c2DMeZNYHu-SHLyQ/s720/jettystart.png"><img style="cursor: pointer; width: 619px; height: 432px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_oGZVDBtb6Hxhz3uEDN-0uHVFeg5dEo-IiKsJSqDTeKiXDVZCkmUlqoYIDe26v5Y-_2KMRNvOOkFE5Ohd1gG_d4OALfLSUpgPqat8a-SKTckqv6JiTDGDJw-Yc_7c2DMeZNYHu-SHLyQ/s720/jettystart.png" alt="" border="0" /></a></span></p><p class="noindent"><span style="font-size:85%;">Jetty Stop</span></p><p class="noindent"><span style="font-size:85%;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhobL9sJpgmP7QCS3M2cSSgwPuvZpTXgu7WmQCGRp21DjlKSJyjHwlAxRY363dppQME9uZ85Fr9cHuM1V9WU9TqtYQkJ_ijVuaARVfxJDxIe6rukIvwLbLJZbjIu7OG3iBJMlYtllwbilg/s720/jettyStop.png"><img style="cursor: pointer; width: 624px; height: 435px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhobL9sJpgmP7QCS3M2cSSgwPuvZpTXgu7WmQCGRp21DjlKSJyjHwlAxRY363dppQME9uZ85Fr9cHuM1V9WU9TqtYQkJ_ijVuaARVfxJDxIe6rukIvwLbLJZbjIu7OG3iBJMlYtllwbilg/s720/jettyStop.png" alt="" border="0" /></a></span></p><p class="noindent"><span style="font-size:85%;"><br /></span></p><p class="noindent"><span style="font-size:85%;">Listo ahora si podemos modificar desde Eclipse nuestra aplicacion Scala y lo vemos reflejado al hacer deploy sobre el web server, </span><span style="font-size:85%;">teniendo como directorios mas importantes:</span></p><p class="noindent"> <span style="font-size:85%;">src/main/scala</span></p><p class="noindent"><span style="font-size:85%;">src/main/web-app<br /></span></p><p class="noindent"><span style="font-size:85%;">src/main/web-app/templates-hidden</span></p><p class="noindent"><span style="font-size:85%;">Algo importante en modificar es en el archivo Boot.scala dentro del package bootstrap.liftweb, al momento de indicarle en que paquete el framework debe buscar las clases de snippets, la linea debe quedar asi para nuestro caso:</span></p><p class="noindent"><span style="background-color: rgb(211, 211, 211);font-size:85%;" >LiftRules.addToPackages("scalademo")</span></p><p class="noindent"><span style="font-size:85%;">En este punto ya podemos modificar los archivos html para mostrar lo que querramos, guardamos y mandamos a correr el proyecto:</span></p><p class="noindent"><span style="font-size:85%;">Run as-> Maven Build-> Seleccionamos la configuracion Jetty_Run_Config</span></p><p class="noindent"><span style="font-size:85%;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4e5XnD_klLvD5ZIOq4ZlD9NvhlNm2W4d7n-3B-rtr2Fvtz8Kf2sOWpXTuHDD6V2QI3U50q_tPt1AIMS5VcBkoMYFaNa8PdKXZ0qySpHYLd7vZH3pydDBc-4i8HaKXA0azaaiDizmBSsI/s800/final.png"><img style="cursor: pointer; width: 670px; height: 395px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4e5XnD_klLvD5ZIOq4ZlD9NvhlNm2W4d7n-3B-rtr2Fvtz8Kf2sOWpXTuHDD6V2QI3U50q_tPt1AIMS5VcBkoMYFaNa8PdKXZ0qySpHYLd7vZH3pydDBc-4i8HaKXA0azaaiDizmBSsI/s800/final.png" alt="" border="0" /></a></span></p><p class="noindent"><span style="font-size:85%;">Listo, tenemos un pequenho inicio a Scala+Lift con Eclipse!<br /></span></p>gishachttp://www.blogger.com/profile/06775830448359587062noreply@blogger.com1tag:blogger.com,1999:blog-1600222101871355960.post-19496195032898118822008-10-20T20:57:00.000-07:002008-10-20T21:37:09.298-07:00Welcome to my world!<span style="font-size:85%;"><span style="font-family:verdana;">En vista a y debido a que, y gracias a todos nuestros auspiciantes (</span><a style="font-family: verdana;" href="http://code.google.com/">Google Code</a><span style="font-family:verdana;">, </span><a style="font-family: verdana;" href="http://www.netbeans.org/">Netbeans</a><span style="font-family:verdana;">, </span><a style="font-family: verdana;" href="http://jasperforge.org/plugins/project/project_home.php?group_id=102">Jasper</a><span style="font-family:verdana;">, </span><a style="font-family: verdana;" href="http://dynamicjasper.sourceforge.net/">Dynamic Jasper</a><span style="font-family:verdana;">, </span><a style="font-family: verdana;" href="http://www.jasypt.org/">Jasypt</a><span style="font-family:verdana;">, </span><a style="font-family: verdana;" href="http://www.hibernate.org/">Hibernate</a><span style="font-family:verdana;">, </span><a style="font-family: verdana;" href="http://www.springframework.org/">Spring</a><span style="font-family:verdana;">, </span><a style="font-family: verdana;" href="http://www.blogger.com/www.jfree.org/jfreechart">JFreeChart</a><span style="font-family:verdana;">, </span><a style="font-family: verdana;" href="https://wizard.dev.java.net/">Java Wizard</a><span style="font-family:verdana;">) y al gran trabajo hecho junto a mi gran amiga </span><a style="font-family: verdana;" href="http://www.facebook.com/profile.php?id=544758133">Karen(Karucita)</a><span style="font-family:verdana;">, al fin hemos terminado nuestro </span><a style="font-family: verdana;" href="http://code.google.com/p/tesis-sicce/">Proyecto de Tesis!</a><span style="font-family:verdana;"> (Ya somos Ingenieros en Sistemas xD), motivo por el cual tengo el tiempo suficiente para crear un blog y publicar cualquier cosa sobre tecnologia relacionada mas con el desarrollo de software! asi que de aqui en mas llenare este espacio con noticias o algun articulo mostrando alguna vivencia de developer!</span><br /><br /><span style="font-family:verdana;">Asi que, welcome to my world</span></span>!!!gishachttp://www.blogger.com/profile/06775830448359587062noreply@blogger.com0