8 July, 2008

Nautilus svn, el tortoise linuxero

Cuando me pasé a ubuntu busqué y rebusqué algo parecido a tortoisesvn, estaba muy acostumbrado a trabajar con el. Al final no encontré nada parecido y me quedé con los clientes de eclipse y netbeans (que están muy bien por cierto), con kdesvn y con la línea de comandos claro.

Pero estos días he descubierto nautilussvn. Un cliente subversion que se integra bastante bien con nautilus el explorador de ficheros de gnome. Le faltan muchas opciones, pero para echar un vistazo a los ficheros modificados y no commiteados o para subir ciertos cambios de una forma ágil esta muy pero que muy bien.

Nautilus svn

Su creador Jason Field ha publicado el proyecto en el repositorio de código de google para todo el que quiera participar, ¡ánimo!.

PD: Acabo de recibir 2 sms de la uoc, he aprobado las 2 asignaturas a las que me presenté, esto merece una gran celebración!! :-).

6 July, 2008

Curso J2EE (9ª,10ª semana) spring

Llegamos a la 9ª semana y le toca el turno a spring, nos extenderemos 2 semanas y un poquito de la siguiente debido a la gran cantidad de herramientas y frameworks con los que podemos integrarlo además aprovecharemos su módulo aop para introducir los conceptos de la programación orientada a aspectos.

Spring no es un framework al uso como los que yo había utilizado, struts, cakephp, jsf. Spring abarca todas las capas de una aplicación, y no solo de una aplicación web, podemos utilizar perfectamente spring para el desarrollo de aplicaciones de escritorio. Spring se compone de diversos módulos siendo indispensable el "core" a partir de este podemos utilizar cualquiera de los existentes dependiendo de nuestras necesidades:

- MVC: Implementación del patrón MVC.

- ORM: Integración con api's de mapeo objeto-relacional (JDO, Hibernate, iBatis).

- AOP: Implementación de programación orientada a aspectos.

- WEB: Contexto de aplicaciones orientado a web. Deberemos utilizarlo para integrar otros frameworks (struts, webwork, etc).

- DAO: JDBC.

Modulos spring

Por esto al principio me chocó un poco la idea que tenía a priori de spring, esperaba un framework típico y me encontré con algo muy diferente. Podríamos decir que spring es el encargado de unir todas las piezas de nuestra aplicación, piezas que pueden ser propias del framework (módulo mvc), o piezas de terceros que se integran a perfección (hibernate, struts, etc). Frameworks como spring se conocen como "contenedores ligeros" y no es el único: http://www.picocontainer.org.

¿Como integra spring todas estas piezas?. Dos conceptos a tener muy en cuenta: inversión de control e inyección de dependencias. Tenemos un montón de información por la red de "que es" y "hace" cada uno aunque a menudo se confunden. Pero digamos que estas dos técnicas hacen posible que spring elimine todas las dependencias y desacople los diferentes módulos que componen un programa, siguiendo el Principio de Hollywood: "no nos llames a nosotros; nosotros te llamaremos a tí".

Para spring un bean será un objecto que el podrá gestionar, lo crea lo destruye lo inyecta donde sea necesario. Así tenemos una interfaz básica BeanFactory que será la encargada de proporcionar los mecanismos necesarios para gestionar estos beans. Para aprovechar las capacidades de spring todo lo que desarrollemos serán beans, solo de esta forma spring podrá inyectar las dependencias que especifiquemos en el fichero de configuración.

Un ejemplo para verlo un poco mas claro:

Tenemos una clase Factura.java:

  1. public class Factura implements Serializable{
  2.    private Integer num;
  3.    private Double importe;
  4.    public Integer getNum() {
  5.       return num;
  6.    }
  7.    public void setNum(Integer num) {
  8.       this.num = num;
  9.    }
  10.    public Double getImporte() {
  11.       return importe;
  12.    }
  13.    public void setImporte(Double importe) {
  14.       this.importe = importe;
  15.    }
  16. }

Tenemos un FacturasManager.java que contiene una lista de facturas y un método que las pinta por pantalla:

  1. public class FacturasManager implements Serializable {
  2.    private List facturas;
  3.    public List getFacturas() {
  4.       return facturas;
  5.    }
  6.    public void setFacturas(List facturas) {
  7.       this.facturas = facturas;
  8.    }
  9.    public void pintaFacturas() {
  10.       ListIterator iterator = facturas.listIterator();
  11.       while(iterator.hasNext())
  12.       {
  13.             Factura f = (Factura)iterator.next();
  14.             System.out.println("Factura Nº:"+f.getNum()+",importe"+f.getImporte());
  15.       }
  16.    }
  17. }

Deberíamos complicarlo un poco mas pero para ilustrar los conceptos anteriores nos sirve.
Ahora tenemos el fichero xml de configuración de spring donde detallaremos los beans y las inyecciones que necesitamos hacer:

  1. <beans>
  2.     <bean id="factMan" class="net.jsanroman.facturas.FacturasManager">
  3.         <property name="facturas">
  4.             <list>
  5.                 <ref bean="factura1"/>
  6.                 <ref bean="factura2"/>
  7.                 <ref bean="factura3"/>
  8.             </list>
  9.         </property>
  10.     </bean>
  11.     <bean id="factura1" class="net.jsanroman.facturas.Factura">
  12.         <property name="num"><value>1</value></property>
  13.         <property name="importe"><value>124.3</value></property>
  14.     </bean>
  15.     <bean id="factura2" class="net.jsanroman.facturas.Factura">
  16.         <property name="num"><value>2</value></property>
  17.         <property name="importe"><value>14.3</value></property>
  18.     </bean>
  19.     <bean id="factura3" class="net.jsanroman.facturas.Factura">
  20.         <property name="num"><value>3</value></property>
  21.         <property name="importe"><value>224.3</value></property>
  22.     </bean>

Estamos instanciando 3 beans tipo Factura desde el propio xml y los estamos inyectando en la propiedad facturas de FacturasManager:

Ahora simplemente necesitamos un método que ejecute lo anterior, como veis una simple case standalone:

  1. private static FacturasManager facturasManager;
  2.    public static void main(String[] args){
  3.       ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
  4.         facturasManager = (FacturasManager)ctx.getBean("factMan");
  5.         facturasManager.pintaFacturas();
  6.     }

Hemos desacoplado las clases Factura y FacturasManager, si en lugar de esas 3 instancias de facturas necesitáramos enviar un listado de las facturas de nuestra BD simplemente necesitaríamos modificar la inyección en el fichero .xml.

De esta forma también podremos integrar un montón de librerías externas.

2 July, 2008

Curso J2EE (8ª semana) struts2

Aunque este fin de semana pasado ya hemos terminado el curso, a mi todavía me queda contaros por encima el contenido de algunas semanas, que espero poder liquidar pronto, aquí va la 8ª, dedicada a struts2.

Otro framework, webwork, nació como un fork de struts añadiendo nuevas ideas y funcionalidades. Allá por el 2005 se anunció la fusión de struts con webwork. En ese momento nació struts2.

El primer cambio cuando pasamos de struts a struts 2 lo encontramos en la configuración de nuestro web.xml, ahora ya no utilizamos el conocido ActionServlet, ni especificamos la ruta de nuestro fichero de configuración struts-config.xml. En struts2 lo cambiamos por un DispatcherFilter que debemos definir en web.xml y será el encargado de gestionar nuestras acciones y de selccionar los interceptores a invocar:

  1. <filter>
  2.     <filter-name>struts2</filter-name>
  3.         <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
  4.     </filter>
  5.     <filter-mapping>
  6.         <filter-name>struts2</filter-name>
  7.         <url-pattern>/*</url-pattern>
  8.     </filter-mapping>
  9. </filter>

El fichero de configuración principal será struts.xml el cual podremos segmentar en tantos ficheros como deseemos para estructurar lo mejor posible nuestras acciones:

  1. <include file="administracion.xml"/>

Ahora nuestras acciones extienden de ActionSupport y aunque siempre acabamos necesitándolo no tenemos que acceder a la request para obtener nuestros parámetros sino que se encarga de hacerlo struts2 mediante inyección de dependencias, ya no necesitamos ActionForm.

Results predefinidos para devolver el estado de una accion, ERRORS, SUCESS,...

Tenemos una serie de interceptores predefinidos (validaciones, login, logger, etc) y podemos definir nuestros propios interceptores, deben extender de AbstractInterceptor y ser declarados en el fichero principal struts.xml.

  1. <interceptors>
  2.      <interceptor name="login" class="net.jsanroman.interceptors.LoginInterceptor"/>
  3.      <interceptor name="logger" class="net.jsanroman.interceptors.LogInterceptor"/>
  4.           <interceptor-stack name="comun">
  5.                <interceptor-ref name="login"></interceptor-ref>
  6.                <interceptor-ref name="logger"></interceptor-ref>
  7.                <interceptor-ref name="validation"></interceptor-ref>
  8.           </interceptor-stack>
  9. </interceptors>

y los asignamos a una acción, podemos asignar un stack o conjunto de interceptores directamente:

  1. <action name="doLogin" class="net.jsanroman.security.controller.LoginAction">
  2.        <interceptor-ref name="comun"></interceptor-ref>
  3.        <result name="input">/login/login.jsp</result>
  4.        <result name="error">/login/login.jsp</result>
  5.        <result>/login/login_ok.jsp</result>
  6. </action>

Añadido concepto de packages y namespace en la definición de acciones en nuestro xml para agrupar acciones:

  1. <package name="facturas" namespace="/facturas" extends="struts-default">
  2.       <action name="Pagar" class="net.jsanroman.security.controller.factura.PagarFacturaAction">
  3.             <result>/facturas/factura.jsp</result>
  4.       </action>
  5.       <action name="Cargar" class="net.jsanroman.common.controller.CargarFacturaAction">
  6.             <result name="error">/facturas/error.jsp</result>
  7.             <result>/facturas/factura.jsp</result>
  8.       </action>
  9. </package>

Nuevos tags para renderizar diferentes elementos html:

  1. <%@ taglib prefix="s" uri="/WEB-INF/struts-tags.tld" %>
  2.    <head><title>Nueva factura</title></head>
  3.    <body>
  4.     <s:form action="guardar" method="post">
  5.        <s:textfield label="Fecha" name="fecha" />
  6.        <s:textarea label="Concepto" name="concepto" rows="6" cols="35" />
  7.        <s:textfield label="Importe" name="importe" />
  8.        <s:submit value="Guardar"/>
  9.    </s:form>
  10.     </body>
  11.  </html>

Validaciones declarativas en xml, uno por acción, PagarFacturaAction-validation.xml

  1. <validators>
  2.      <field name="importe">
  3.           <field-validator type="requiredstring">
  4.               <param name="trim">true</param>
  5.                <message>Importe factura obligatorio</message>
  6.           </field-validator>
  7.      </field>
  8. </validators>

o mediante anotaciones:

  1. @Validation
  2. public class Factura {
  3.     private float importe;
  4.     @RequiredStringValidator(message="Importe factura obligatorio", key="validation.fieldRequeried")
  5.     public String getImporte() {
  6.         return importe;
  7.     }
  8. ...

Como veis muchos cambios, y muchos mas que nos quedan por descubrir.

http://www.infoq.com/minibooks/starting-struts2
http://struts.apache.org/2.x/

Powered by WordPress
Bajo licencia Creative Commons
Contacto sanroman.javier at gmail.com