Trabajo relacionado con Java

16 de Diciembre de 2008

URI con seguridad usuario clave

Archivado en: Desarrollo — jansoblog @ 5:04 pm
Tags:

Para cualquier tipo de URI el formato es:
protocol://usuario:clave@server:port/path

Ejemplos
http://user:clave@xxx.com/paginaSegura
ftp://user:clave@xxx.com/directorioSeguro
http://user:clave@xxx.com/paginaSegura

13 de Octubre de 2008

Modificación look & feel pentaho ADHOC

Archivado en: Desarrollo — jansoblog @ 1:48 pm
Tags: , , , ,

Adhoc es el nombre del sistema de creación de informes directamente por el usuario final en cuatro pasos.

Modificación de la presentación:

El primer punto se cambiar los css $PENTAHO_HOME$/adhoc/styles:

  • adhoc.css
  • repositoryBrowserStyles
  • styles-new
  • styles-new.p

Las imágenes está en en $PENTAHO_HOME$/adhoc/images

El html principal es el siguiente waqr.html. Sobre éste los js modifican en tiempo de ejecución su contenido, mostrando y ocultando DIVs o cambiando el contenido de los DIVs.

Los js, están agrupados de la siguiente manera contraoller, modelo y ui. Modelo-vista- controlador y un paquete extra (common) donde hay utilidades auxiliares como : leer xml, tratar cadenas, mostrar por pantalla,….

Gran parte del texto que aparece se puede configurar en el archivo message_strings.js del directorio en $PENTAHO_HOME$/adhoc/js/ui/messages/nls/

Recomendaciones:
Si sólo se quiere cambiar un poco la presentación sólo es necesario modificar los css, images y message_strings.js.

Modificación del Look & Feel de pentaho

Archivado en: Desarrollo — jansoblog @ 1:38 pm
Tags: , , , ,

Modificación de la presentación de Pentaho:

El primer punto se cambiar los css.

  • %TOMCAT_HOME%/pentaho-styles/css
  • %TOMCAT_HOME%/pentaho-styles/img

También se puede modificar el estilo el menú

  • %TOMCAT_HOME%/pentaho-styles/menu/css
  • %TOMCAT_HOME%/pentaho-styles/menu/js

Para modificar el contenido del menú se necesario modificar los archivos:

  • %PENTAHO_SOLUTION%/system/custom/xsl/*menu*.xsl

Para añadir un idioma hay que ir a

  • %PENTAHO_HOME%/WEB-INF/clases/org/pentaho/locale.

Como última opción se puede modificar la plantilla general %PENTAHO_HOME%/jsp/index.jsp y otros archivos para la administración de pentaho.

22 de Agosto de 2008

Configurar Tomcat 5.5 JNDI datasource con eclipse

Archivado en: Desarrollo — jansoblog @ 10:34 am

Para configurar el datasource de una aplicación web para el Tomcat 5.5 desde eclipse.

Configurar server.xml

<Resource name="jdbc/miDS" auth="Container" type="javax.sql.DataSource"
maxActive="20" maxIdle="5" maxWait="10000"
username="sa" password="" driverClassName="org.hsqldb.jdbcDriver"
url="jdbc:hsqldb:hsql:localhost:1666"/>

 

configurar server.xml

configurar server.xml

Configurar web.xml


<resource-ref>
<res-ref-name>jdbc/miDS</res-ref-name>
<res-type>javax.sql.DataSource </res-type>
<res-auth> container </res-auth>
</resource-ref>
 
 

 

Acceder al datasource desde el código

InitialContext jndiContext = new InitialContext();
DataSource ds =
(DataSource)jndiContext.lookup("java:comp/env/jdbc/miDS");

 

Configurar el resource se puede hacer en otros sitios, pero también hay que configurar eclipse para decirle de dónde coje la información de la configuración del tomcat.

16 de Julio de 2008

Usar JUnitPerf con test desarrollados con Junit 4 jdk 1.5

Archivado en: Desarrollo — jansoblog @ 6:40 am
Tags: , ,

Mientras la gente de JUnitPerf no desarrolle una nueva versión de su extensión de JUnit, compatible con los test desarrollados en JUnit 4 con el JDK 1.5, la extensión JUnitPerf no funciona correctamente con este tipo de test.

El equipo de Junit ya vió venir este problema y creó un adaptador para ayudar a la integración de estas extensiones mientras no se actualicen.

A continuación pongo un ejemplo de cómo se crearía una suite para JUnitPerf teniendo en cuenta que MyTest está desarrollado con JUnit 4, anotations, etc.

public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTest(new LoadTest(new JUnit4TestAdapter(MyTest.class),
1 /* user */, 10 /* iterations */));
suite.addTest(new LoadTest(new JUnit4TestAdapter(MyTest.class),
10 /* user */, 1 /* iterations */));
return suite;
}

Si no conoces JUnitPerf y quieras hacer pruebas de carga y rendimiento en tus test de unidad, míratelo.

Por los posibles comenarios sobre JUnitPerf y si es relevante hacer pruebas de carga en test de unidad, quiero comentar que para mi no son especialmente válidos estos test y mucho menos si lo utilizas para medir tiempos o hacer pruebas de que una determinada funcionalidad responde en X segundos, pero si lo que quieres hacer es comprobar que una determinada funcionalidad, se ejecuta correctamente cuando es accedida por N usuarios, JUnitPerf es una buena herramienta para ello.

4 de Junio de 2008

Probando Grails II

Archivado en: Desarrollo — jansoblog @ 9:41 am
Tags: , ,

Como me convenció bastante Grails he dedido seguir trabajando un poco en la aplicación.

He añadido un campo autocomplete y un calendario para las fechas.

He usado el plugin richui y en total he dedicado 3 horas.

A mejorar:

Localización de los mensajes y formatos. Sería interesante que se completara el plugin con los mensajes de otros idiomas.

En general creo que los tags que ofrece este plugin se pueden mejorar, pero tiempo al tiempo.

Referencias:

Documentación RichUI plugin : http://docs.codehaus.org/display/GRAILS/RichUI+Plugin

Otros plugins : http://docs.codehaus.org/display/GRAILS/Plugins

2 de Junio de 2008

Probando Grails

Archivado en: Desarrollo, Negocio — jansoblog @ 9:29 am
Tags: , ,

Grails usa un sistema denominado “convention” que yo traduciría por “acuerdo”, en vez de usar el clásico sistema de configuración con XML y esta es una de sus claras ventajas a la hora de conseguir un rápido desarrollo. Además usa Groovy, un lenguaje de scripting basado en Java, lo cual reduce la cantidad de código necesaria.

Pero no sólo eso, hay otros elementos que ayudan a un desarrollo rápido. El sistema de plugins permite entre otras cosas, instalar un plugin usando simplemente el comando “grails install-plugin XXX” y empezar a utilizarlo sin tener que configurar nada. Hay plugins para muchas cosas, por ejemplo RIA, entendido como usar librerías javascript para mejorar la presentación o hacer llamadas AJAX, también puedes incorporar jasper reports o hacer la presentación con FLEX.

También es muy interesante el uso de plantillas, aunque lo permite, no es necesario generar todo el código necesario para un mantenimiento, o CRUD como dicen algunos, puedes tenerlo definido como plantillas tanto para archivos groovy (controlador) como para archivos gsp (vista).

Para aprender he decido hacer una pequeña aplicación de gestión de las compras de casa. Básicamente es una aplicación para mantener 7 tablas, una de ellas con una relación maestro detalle.

Para desarrollar la aplicación completa he necesitado 4 horas incluyendo en este tiempo la instalación de Grails. Lo que da una medida de la mejora de productividad que conlleva.

Cosas a mejorar:

Facilitar el desarrollo en IDE: Me refiero a syntax highlight, autocompletado, refactor y esas cosas. Hay un plugin para eclipse pero aún le falta mucho. IntelliJ IDEA puede que tenga un entorno de desarrollo mejor para Groovy pero no lo he probado.

Mejorar el control de errores: Como pasa en muchos frameworks los mensajes de error no son claros ni completos o incluso despistan más que ayudan.

Riesgos:

Se trata de un framework muy joven, la versión 1.0 es de febrero de 2008, lo cual implica que es muy dinámico, que hay cosas que pueden cambiar en el futuro o que tu aplicación o tu plugin deje de funcionar dramáticamente si actualizas la versión por un bug del framework. Quiero añadir que este tipo de cosas ha pasado al actualizar a Grails 1.0.2.

Referencias:

Grails : http://grails.org/

Documentación Grails : http://dist.codehaus.org/grails/

Tutorial IBM : http://www.ibm.com/developerworks/java/library/j-grails01158/index.html

Groovy : http://groovy.codehaus.org/

23 de Octubre de 2007

Ciclo de Vida en JSF

Archivado en: Desarrollo — jansoblog @ 11:05 am
Tags: ,
    Hay que tener en cuenta que en la web existen discursos mucho más completos y mejores acerca de este tema, pero la idea es que éste resulte “coloquial” a los desarrolladores.    El diagrama que representa el ciclo es el siguiente, desde un punto de vista funcional y adaptado a una terminología sencilla:
Ciclo de vida JSF

  A continuación se describe este procedimiento siguiendo el orden numérico de las distintas fases y los posibles caminos alternativos:


    La primera fase puede denominarse como “Aplicar los valores de la petición” (ver recuadro 1). En ella se van recorriendo todos los componentes del formulario siguiendo la jerarquía padre-hijo al mismo tiempo que se recuperan sus valores a partir de los parámetros de la petición o request enviada al servidor. El valor se asigna a cada componente en su propiedad submittedValue.
    Esto ocurre siempre excepto en dos casos: si el componente está deshabilitado (disabled = true) o si posee una condición que indica cuándo debe pintarse en pantalla(atributo ‘rendered’).
    A continuación tendrá lugar bien la fase de validaciones o bien la ejecución de cada uno de sus eventos asociados dependiendo del valor del atributo ‘immediate’ de los componentes de la página (ver al final el apartado “Uso del atributo ‘immediate’.”).

    Siguiendo la secuencia normal del ciclo, la siguiente fase que tiene lugar es la de “Procesamiento de las validaciones” (ver recuadro 2). Este proceso consiste en la validación del dato suministrado por el usuario en función de las reglas de validación definidas para el componente.
    Es común el uso de un validator o un converter, que se aplica sobre el submittedValue. Si no se produce ningún error de validación o de conversión, el valor del submittedValue de cada componente válido pasa a ser null y entonces se almacena en su ‘value’ el dato convertido al tipo que tenga la propiedad del bean a la que se asignará posteriormente.
    En caso contrario, el ciclo de vida avanza directamente hasta la fase de presentación de la respuesta.

    Durante la fase de “Proceso de Eventos”  (ver recuadro 3) se llevan a cabo todos los eventos asociados a las acciones realizadas por el usuario.

    Pasamos a la próxima fase del ciclo: “Actualización de los valores del Modelo” (ver recuadro 4). Tras las validaciones y/o ejecución de los eventos tiene lugar la asignación del ‘value’ de los componentes a los atributos del bean.

    Entonces llegamos a la fase conocida como “Invocar la aplicación” (ver recuadro 5) en la que se usan los valores del bean para ejecutar la lógica de negocio y se llevan a cabo las operaciones correspondientes a las acciones del usuario.

    Por último, tiene lugar la fase: “Presentación de la respuesta” (ver recuadro 6).  La implementación de JavaServer Faces delega su autoridad en el contenedor JSP para enseñar la página que el usuario ve por pantalla, y donde todos los campos están informados con su valor en ese momento.
    Si se produjo un error en la fase de validación, se muestra la response (pantalla de respuesta) con los valores que introdujo el usuario y además un mensaje informativo del error. El valor que aparecerá en pantalla para cada componente de la página será el primero no nulo que el servidor encuentre en la secuencia:

Componente.submittedValue –> Componente.value –> Bean.attribute

 

Uso del atributo ‘immediate’

    El atributo ‘immediate’ de los componentes de un formulario está presente en la mayoría de las fases del ciclo de vida.
    Ya en la primera fase del ciclo se comprueba el valor de dicho atributo. Si vale true, el ciclo avanza hasta la tercera fase, saltándose las validaciones pertinentes. En caso contrario, se continúa el ciclo normal hacia la fase 2.
    Es importante señalar en este punto que si ‘immediate’ no se indica su valor es false, ya que así está definido en la declaración de atributos de JSF. Y además es importante saber que el hecho de asignarle el valor true  implica no tener acceso a los valores de los campos del formulario así como a los errores que se hubieran producido.

Glosario

Componente: elemento que forma parte del formulario y provee funcionalidades para interactuar con el usuario. Puede ser de diferentes tipos (caja de texto, botón, control de selección…) y el usuario “completa” el formulario a través de su modificación.

Converter: se utiliza cuando es necesario convertir el dato introducido por el usuario al tipo apropiado. Por ello hay que indicar como nombre el de una clase bean que implemente la interfaz Converter.

Evento: acción que queremos que se produzca al cambiar el valor del componente. Por ejemplo, el caso de un selectOneMenu cuando cambiamos la opción marcada del menú desplegable. Solemos indicar estas acción a través de los atributos ‘onchange’, ‘onblur’, ‘onclick’, etc. en el código jsp.

Evento de acción: acción declarada en el atributo ‘action’ de un componente. A cada botón que exista en una página le corresponde una acción (no necesariamente distinta a las demás), y que nosotros solemos denominar con los nombres “doXxxAction” o “goXxxAction”. Por ejemplo: doActualizarAction(), goAtrasAction().

Nota: JSF entiende ‘evento’ como cualquier acción realizada por el usuario. Por ejemplo: pulsar en un botón, hacer clic sobre un link, escribir en un inputText, etc. Como se lee un poco más arriba, nosotros distinguimos entre ‘eventos’ propiamente dichos, y ‘eventos de acción’.

SubmittedValue: valor introducido por el usuario en el formulario.

Validator: responsable de asegurar que el valor ingresado por un usuario es aceptable. Uno o más validadores pueden ser asociados con un solo componente y se definen en clases Java independientes.

Referencias

Mi agradecimiento a Inma Molina por la edición de este artículo y el diseño de la imagen.

29 de Junio de 2007

Gestión de la auditoría con Spring 2.0

Archivado en: Desarrollo — jansoblog @ 9:22 am
Tags: , ,

Spring 2.0 introduce dos nuevos scope para quienes desarrollamos aplicaciones web.
Esta nueva funcionalidad simplifica un trabajo tan arduo como la gestión de auditoría.

Para que el ejemplo quede más claro, como gestión de auditoría vamos a enteder que se indique en el log qué usuario ha realizado una determinada acción.

Realizar esta tarea sin Spring, consistiría principalmente en pasar un nuevo argumento a cada uno de los métodos de la lógica de negocio inidicando el usuario.

Existen otras formas que no voy a discutir, como poner la información en ThreadLocal.

A continuación, indicaré los pasos para crear un bean de sessión en Spring y hacer que un servicio singleton lo reciba, y de esta manera pueda hacer log del usuario y la acción.

Configurar web.xml (fragmento)

<listener> 
<listener-class>
  org.springframework.web.context.request.RequestContextListener
  </listener-class>
 </listener>
 <listener>
  <listener-class>
  org.springframework.web.context.ContextLoaderListener
  </listener-class>
 </listener>

Crear el bean con la información del usuario

package sadiel.rrhhsas.model.comun.objnegocio;
public class UsuarioSession implements Serializable, IUsuario {
String usuario; // Código del usuario
 // getters y setters
  // ..
}

Crear el servicio


package sadiel.rrhhsas.model.adm.usu.service.impl;
public class UsuarioServiceImpl implements IUsuarioService {
IUsuario usuario; //Usuario de session
// the logger for this class
private Log logger = LogFactory.getLog(this.getClass());
/**
  * Valida a un usuario a partir de su usuario y su clave.
  * Introduce el usuario en la session para que sea accesible por otros servicios
  * @param clogin
  * el usuario que usamos
  * @param cclave
  * la clave que usamos
  * @return true
  */
 public boolean login(String clogin, String cclave)
  throws UsernameNotExistException {
// Valido al usuario
  // ...
  // Informo en el usuario de sessión el código del usuario conectado
  usuario.setUsuario(user.getCUsuario());
return true;
}
/**
* @see IUsuarioService#actualizar(Object o)
*/
public void actualizar(Object o) {
this.logger.debug("El usuario "+usuario.getCUsuario() +
" modifica el objeto "+o);

// Resto del servicio
// ..
}
/**
* Set the user in session
* It will be used by the Spring IOC container.
* @param usuario the usuario to set
*/
public void setUsuario(IUsuario usuario) {
this.usuario = usuario;
}
}

Configurar applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<bean id="Usuario"
  class="sadiel.rrhhsas.model.comun.objnegocio.UsuarioSession"
  scope="session">
  <aop:scoped-proxy/> <!-- Esto hay que incluirlo en los beans
  con scope="session" si los queremos
  utilizar en otros bean singleton -->
 </bean>
<bean id="iUsuarioService"
  class="sadiel.rrhhsas.model.adm.usu.service.impl.UsuarioServiceImpl" >
  <property name="usuario">
  <ref bean="Usuario" />
  </property>
 </bean>
</beans>Por supuesto si quisieramos que todos los servicios recibieran al usuario, lo que habría que hacer es definir un servicio abstracto y hacer que todos los servicios fueran hijos de este, pero de eso bloquearé otro día.Y eso es todo, algún comentario sería apreciado.

26 de Junio de 2007

Ejemplo del sistema de acceso a los recursos en Spring 2.0

Archivado en: Desarrollo — jansoblog @ 9:21 am
Tags: , ,

En este ejemplo nos vamos a concentrar en la configuración del SessionFactory de Hibernate y las diferentes alternativas que nos ofrece el sistema de abstracción de recursos para simplificar la configuración y mantener distintas configuraciones.

A continuación veamos una configuración básica del sessionFactory de Spring para Hibernate con conexión a Oracle.

<bean id=“sessionFactory”

      class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>

      <property name=“dataSource”>

            <ref bean=“dataSource” />

      </property>

      <property name=“hibernateProperties”>

            <props>

             <prop key=“hibernate.dialect”> org.hibernate.dialect.Oracle9Dialect

             </prop>

             <prop key=“hibernate.show_sql”> false</prop>

             <prop key=“hibernate.cglib.use_reflection_optimizer”> true

             </prop>

            </props>

      </property>

      <property name=“mappingResources”>

           <list>           <value>sadiel/rrhhsas/model/adm/usu/objnegocio/Perfil.hbm.xml</value>               <value>sadiel/rrhhsas/model/adm/usu/objnegocio/Usuario.hbm.xml</value>                 <value>sadiel/rrhhsas/model/adm/usu/objnegocio/UsuarioPerfil.hbm.xml</value>

            </list>

      </property>

</bean>

El primer problema que podemos ver es que la lista de mappingResources va a crecer continuamente y se hará muy extensa. Cualquiera ha trabajado en un proyecto con 100 tablas o más.

Afortunadamente LocalSessionFactoryBean tiene otra propiedades de tipo Resource[] que no va a permitir solucionar este problema. Y la configuración quedaría de este modo.

      <property name=“mappingLocations”>

            <!– Cargamos todos los ficheros hibernate que haya en el classpath dentro del paquete –>

            <value>classpath:sadiel/**/*.hbm.xml</value>

      </property>

Quizás más sutil, pero tampoco parece coherente tener una configuración compleja como la configuración de hibernate, dentro de la configuración de la aplicación. Sobretodo pensando que podemos tener distintas configuraciones para entornos diferentes, o para clientes diferentes.

En este caso LocalSessionFactoryBean no nos puede ayudar directamente ya que no tiene una propiedad de tipo Resource para configurar las propiedades de hibernate. Sin embargo si que podemos hacer referencia a otro bean que contenga estas propiedades.

<bean id=“sessionFactory”

      class=“org.springframework.orm.hibernate3.LocalSessionFactoryBean”>

      <property name=“dataSource”>

            <ref bean=“dataSource” />

      </property>

            <property name=“hibernateProperties”>

                  <ref bean=“hibernateProperties” />

            </property>

      <property name=“mappingLocations”>

            <value>classpath:sadiel/**/*.hbm.xml</value>

      </property>

</bean>

<bean id=“hibernateProperties”

      class=“sadiel.rrhhsas.model.comun.util.ResourcePropertiesUtil”>

      <property name=“propertiesLocations”>

            <value>classpath:hibernate.properties</value>

      </property>

</bean>

De esta manera volvemos a usar el tradicional archivo de configuración hibernate.properties.

La implementación de ResourcePropertiesUtil es muy sencilla, pero la incluyo por completitud.          

package sadiel.rrhhsas.model.comun.util;

public class ResourcePropertiesUtil extends Properties {

       private Resource[] propertiesLocations;

      

       public void setPropertiesLocations(Resource[] propertiesLocations) throws IOException  {

             this.propertiesLocations = propertiesLocations;

             for (Resource resource : propertiesLocations) {

                           super.load(resource.getInputStream());

             }

       }

}

Suponiendo que tenemos que mantener diversas configuraciones, podríamos definir el bean con diferentes propiedades y obtener una de ellas según otro parámetro de configuración. 

Existen otras propiedades que pueden aprovechar esta aproximación de la configuración. Trabajando con Spring 1.1 sólo era posible definir la caché de segundo nivel de Hibernate en cada uno de los fichero hbm. Pero desde la versión de Spring 1.2 es posible informar la caché de clases en la propiedad entityCacheStrategies y la caché de colecciones en la propiedad collectionCacheStrategies, ambas de tipo Properties.  

Dejo el resto a vuestra imaginación. 

Referencias

http://www.springframework.org/docs/reference/resources.html

« Entradas anterioresEntradas siguientes »

Blog de WordPress.com.