09 September 2008

Martin Gardner’s New Mathematical Library

Martin Gardner esta sacando versiones actualizadas de sus clásicas columnas de Juegos Recreativos de la Revista Scientific American llamada The New Martin Gardner Mathematical Library. Los editores son de nivel mundial: Donald J. Albers, Gerald L. Alexanderson, John H. Conway, Richard K. Guy, Donald E. Knuth, Peter L. Renz.

Además en el blog de Cambridge se esta regalando/sorteando copias gratis al resolver un puzzle clásico de Gardner, cada semana. Van a ser 6 libros, asi que todos pueden concursar. Lo interesante es que si uno responde mejorando la respuesta ya conocida se supera el filtro del sorteo y tendrá la chance de ganar el libro directamente, pero lejos es mejor la satisfacción lograda al dar una respuesta mejor a algún problema del mítico Gardner.

http://www.cambridge.org/series/sSeries.asp?code=NGML

https://www.cambridge.org/core/series/new-martin-gardner-mathematical-library/F9984B4DE23B5BF13BB06E332D9280B7

 

10 June 2008

J2ME Game Development - Mex al Rescate

This game (not finished) was based on fiction characters to create a mixture between maze/puzzle and action to play in mobile phones.

The big achievement of this project was to design a complete game with characters, levels, bosses, etc. being this one of the hardest process as Chris Crawford mentions in his classic book The Art of Game Design.

The principal J2ME literature and game framework was based on the famous book:
J2ME Game Programming, Martin Wells, Premier Press 2004, ISBN : 1-59200-118-1 , this has a funny rhetoric to explain how to obtain the best solutions to typical problems developing for MIDP-1, by limitations of this architecture. Its source code is freeware to be used and learn from it, any doubts please contact the author, who answered me questions about it.


The artwork was made by Guden, which becomes the most professional Project’s part.

The music at the cover page was made by Mex, which is the same principal character of the game :)

All source code, music, graphics are under license GPL v2.0

Binaries: MexRescate-bin.zip
Source Code: MexRescate-src.zip

You can download it and contribute it at http://sourceforge.net/projects/mexrescate





Este juego (no-terminado) fue basado en caracteres ficticios para generar una mezcla entre laberinto/puzzle y acción para jugar en celulares.

El gran mérito de este proyecto fue el poder diseñar un juego completo con caracteres, niveles, jefes, etc. siendo esta parte una de las más complejas tal como Chris Crawford menciona en su clásico libro The Art of Computer Game Design.

La literatura J2ME y marco de trabajo del juego fue basado en el famoso libro:
J2ME Game Programming, Martin Wells, Premier Press 2004, ISBN : 1-59200-118-1 , este posee una entretenida retórica para ir explicando como soluciono de mejor manera típicos problemas para MIDP-1, por su misma arquitectura con límites. Siendo su código freeware para su uso y aprendizaje, cualquier duda por favor contacten al autor que de muy buena disposición me contestó dudas al respecto.

La gráfica fue hecha por Guden, llegando a ser lo mas profesional del proyecto.

La música de introducción fue hecha por Mex, quien es el mismo personaje principal del juego :)

Todo el código fuente, música, gráficos esta bajo licencia GPL v2.0

Binarios: MexRescate-bin.zip
Código FUente: MexRescate-src.zip

Puedes bajarlo y contribuir en: http://sourceforge.net/projects/mexrescate





24 January 2008

Falsos Amigos

Hace tiempo que he tenido la inquietud del mal uso de traducciones de palabras de Inglés a Castellano. Es muy común sobre todo en mi area (programación) que se diga libreria a una biblioteca por el simple hecho que en Inglés es library. La primera página web que recuerdo haber leido que hace referencia a este fenómeno es del Profesor Ricardo Baeza.


Después empecé a encontrar diferentes palabras que ocurria lo mismo como interface, deprecate, actually, etc.

Por último navegando en la web me doy cuenta que este tipo de palabras están identificados por los linguistas/traductores como Falsos Amigos (simpático nombre), inclusive existen diccionarios al respecto. Además existen varias páginas web de listas de falsos amigos dentro de las cuales destacan cuales tienen una lista bastante grande y con explicación del falso amigo: Saber Inglés y la siempre útil Wikipedia.

26 September 2007

Precedence Operator

Kernighan & Pike in The Practice of Programming says ``Parenthesize to resolve ambiguity. Parentheses specify grouping and can be used to make the intent clear even when they are not required.'' p.6-7.

Many times the programmers use a few parenthesis to save code, however this is error-prone at operator precedence, a good concrete example I found was for Unpaws project made in Pascal, where the unary logic "not" operator has more precedence over the Set than the enumeration.

Fix diff patch:
530c530
< else if not (c in[6,13,16,17,18,19,20,21,22,23]) then inc(XPos);
---
> else if not c in[6,13,16,17,18,19,20,21,22,23] then inc(XPos);


Also from A Programmer's Guide to Java Certification, Second Edition says respect to unary operators: ``Expressions where variables are modified multiple times during the evaluation should be avoided, because the order of evaluation is not always immediately apparent.'' p.64

31 July 2007

Neo-vintage: Checkboxes in Struts

This is a small tip, but for its awkwardness, I'm publishing here because there is no much information about it (although it's quite old).

Just it says in the Struts' API, we have to leave in false every checkbox in the form, if that Action has Session scope otherwise the checkboxes keep those values. The reset() method doesn't work for it (Listing 1).

The other trick is to use a dummy variable to keep the values from the form modified by the user, because when we are in the Action the values is lost in the checkbox and it can be changed based on this dummy variable updating on JSP by Javascript then in the Java code (Listing 2 & 3).





Este es un pequeño consejo, pero por su extrañeza, lo estoy publicando aca porque no hay mucha información al respecto (aunque es bastante viejo).

Como dice en el api de Struts hay que dejar en falso todos los checkboxes si ese Action es de scope de Session o si no se queda estaticos esos valores. El metodo reset() no funciona para tal caso.(Listing 1)

El otro truco es usar una variable auxiliar para mantener los valores desde el formulario modificado por el usuario, porque cuando estamos en el Action los valores se pierden en el checkbox y puede ser cambiado basandose en esta variable auxiliar actualizandola en el jsp a traves de javascript y despues en el codigo Java (Listing 2 & 3).

http://struts.apache.org/1.x/apidocs/org/apache/struts/action/ActionForm.html
http://husted.com/struts/tips/007.html



Listing 1
//let's assume we run through a collection of checkboxes, we have to assign to false
Collection contracts = (Vector)form.get("contracts");
Iterator it = contracts.iterator();
while (it.hasNext()) {
   Contract contract = (Contract)it.next();

   if(contract.isSelected()){
   //here we do our business, if the checkbox is selected

   ContractPdf cpdf = new ContractPdf();
   cpdf.setP_id_contract( (int)contract.getNum_contract() );
   //.... more code
}

//because it's a checkbox and has session scope we assign to false.
contract.setSelected(false);
}

Listing 2

//asign dummy values depending of checkbox
f = document.forms[0];

if (f.p_all.checked) {
   f.p_all.value = "ALL";
   f.p_all_dum.value = "on";
} else {
   f.p_all.value = "NONE";
   f.p_all_dum.value = "off";
}

Listing 3

//update the checkbox parameter based on the dummy variable on Java tier.
if("on".equals((String)formulario.get("p_all_dum"))){
   formulario.set("p_all", "ALL");
}else{
   formulario.set("p_all", "ALL");
}


30 July 2007

Ninety Ninety Rule

http://en.wikipedia.org/wiki/Ninety-ninety_rule

``The first 90% of the code accounts for the first 90% of the development time. The remaining 10% of the code accounts for the other 90% of the development time.''

Good criteria, It happens lately with projects at my job. Even better is what says at the end of the article, where the number you have calculated has to be multiply by 2 or even better by Pi (.31415 :P).




"El primer 90% del código toma el primer 90% del tiempo de desarrollo. El 10% restante del código toma el otro 90% del tiempo de desarrollo."

Buen criterio, me ha pasado últimamente con proyectos del trabajo. Mejor aun es lo que dice al final es interesante donde dice que el tiempo mejor calculado por uno hay que multiplicarlo por la constante 2 (Aranda2003) y mejor aun por Pi. ( 3.1415 :P ).

19 June 2007

ArrayList and Remove

La solucion esta aca: http://eggeral.blogspot.com/2007/12/removing-items-from-list-in-java.html

ejemplo 11.7 del libro de certificacion de java tb esta bueno :P

esto me recuerda a la progamacion tallarin y lo que dijsktra y knuth (en menor grado, ver documento dele) han luchado de sacar el goto...

el libro de certification java que estoy leyendo dice que remove siempre usarlo con el patron implementado en java.util Iterator, asi siempre borra el ultimo next() o previous() y se evita este tipo de problemas.


import java.util.ArrayList;
import java.util.List;


public class Listas {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub

//BUEN EJEMPLO de como no remover.

List lis = new ArrayList();

for(int i=0; i<6; i++){ lis.add(i, ""+i); } System.out.println("inicio"); for(int i=0; i<6; i++) { System.out.println(i+"="+lis.get(i)); } System.out.println("sacamos y no sale el 4!"); for(int i=0; i
if(i==3){
lis.remove(i);
}else{
System.out.println(i+"="+lis.get(i));
}
}

System.out.println("final");
for(int i=0; i

System.out.println(i+"="+lis.get(i));
}

}

}


------------------------------------------------------------------------------------------

Segundo ejemplo del libro de certificacion:


11.7
What will be the output from the following program?
import java.util.*;
public class Iterate {
public static void main(String[] args) {
List l = new ArrayList();
l.add("A"); l.add("B"); l.add("C"); l.add("D"); l.add("E");
ListIterator i = l.listIterator();
i.next(); i.next(); i.next(); i.next();
i.remove();
i.previous(); i.previous();
i.remove();
System.out.println(l);
};

};
Select the one correct answer.

  1. It will print [A, B, C, D, E].
  2. It will print [A, C, E].
  3. It will print [B, D, E].
  4. It will print [A, B, D].
  5. It will print [B, C, E].
  6. It will print throw a NoSuchElementException.


11.7
(b)
The remove() method removes the last element returned by either next() or previous(). The four next() calls return A, B, C, and D. D is subsequently removed. The two previous() calls return C and B. B is subsequently removed.

11 April 2007

The Stanford GraphBase: 1990 Football Season

This book is -as the title says- a platform for combinatorial computing, based on literate programming also developed by Knuth. It has good sets of data, samples and good and speak at length on of them.

There are several challenge problems and one on unsolved most popular is the 1990 season football: Stanford against Harvard. In the book appears Knuth's best solution, however later appears a research made by Buel Chandler with genetic algorithm obtaining a better result and lately in 2002 Mark Cooke found an even better (the best until now).

Despite to these solution this is a similar to TSP, where still is unknown the best solution, then you can give time to research on this problem.

A nice problem was to do a Regular Expression to parse from the file of games the teams, score and stats from reporters. My best solution is this huge RegExp: (which is accurate enough and to be used with java.util.regexp).

([A-Z]\\&?\\-?)+\\ (([A-Z][a-z]*\\\\?\\&?\\,?\\-?\\ ?)+\\(([A-Z][a-z]+\\-?\\'?\\ ?(\\\\\\&)?\\ ?)+\\)([A-Z][a-z]+\\ ?\\-?)+)\\;[0-9]*\\,[0-9]*\\;[0-9]*\\,[0-9]*

There are 120 teams (nodes) with 638 games (edges). The following graph shows the season:

Knuth has provided all the files for the Stanford Combinatorial platform, where you can find the football.dat file with all the teams and games between them. Above is the graph representing the whole season and following is the data in a more graph viewing of the games (different from the original file that is a single row result of a game pattern).

21 March 2007

JAAS y SecurityFilter

La seguridad es uno de los aspectos a resolver con importancia en estos dias tal como nos dice Cobit y también diferentes ISO's, y por ello un punto importante dentro de cualquier proyecto.

La seguridad se centra sobre dos conceptos básicos: autenticación y autorización. Usuarios se autentican al sistema probando que son lo que dicen ser, por mientras la autorización permite/no-permite acceso a ciertas áreas de la aplicación.

La arquitectura J2EE tiene resuelto (y sus contenedores) este paradigma a través de Java Authentication and Authorization Service (JAAS), la cual es un conjunto de packages con servicios para autenticar y controlar de acceso de una manera centralizada (en un descriptor), conviviendo con el contenedor web que la aplicación este utilizando (Jakarta Tomcat, JBoss, otros).


Esta forma de seguridad puede ser administrada a base del contenedor (container-managed security) o de la aplicación (application-managed security).

1. Esta primera opción, de tener dependencia del contenedor, aumenta la complejidad de administración ya que hay que preocuparse de este contenedor en particular aparte de la aplicación como tal, quedando dividida y preocupándose de ambas. (Ejemplo especificar el repositorio donde se encuentra el real, nombre de usuario, password de roles, etc.).

2. La segunda forma es lograr que la aplicación posea toda la responsabilidad haciéndola más compleja de desarrollar y logrando que su escalabilidad queda segmentada a la solución hecha. La solución implementada en nuestro proyecto es una solución híbrida en la cual dejamos la responsabilidad de la seguridad a la aplicación (autenticación y autorización) a través de un robusto proyecto open source llamado SecurityFilter que genera filtros Servlet para su control. Se logra tener la flexibilidad de una seguridad de aplicación, logrando dejar independiente el contenedor (por ejemplo por su posible migración de arquitectura de conexión de base de datos).

Autenticación Form-Based + SecurityFilter

Los contenedores web J2EE ofrecen tres tipos de mecanismos de autenticación: basic, form-based, y autenticación mutua. La mayoría de las aplicaciones web usan el tipo de form-based ya que permite que la interfaz del usuario sea personalizable (HTML). La autorización es implementada por los contenedores a través de roles de seguridad definidos en el descriptor de la aplicación web (web.xml).

SecurityFilter usa la misma arquitectura que Form-Based donde se configura a través de descriptores en la aplicación.

Existe web.xml donde colocamos el uso del filtro de servlet en la aplicación y que realmente es nuestra forma de seguridad, esta se ve así:

<filter>
  <filter-name>Security Filter</filter-name>
  <filter-class>org.securityfilter.filter.SecurityFilter</filter-class>
  <init-param>
    <param-name>config</param-name>
    <param-value>/WEB-INF/securityfilter-config.xml</param-value>
    <description>Configuracion</description>
  </init-param>
  <init-param>
    <param-name>validate</param-name>
    <param-value>true</param-value>
    <description>Validar debe ser verdadero</description>
  </init-param>
</filter>


Con ello nos permite personalizar cuales son las páginas de ingreso y no-autorización a la aplicación (con sus URLs respectivas):

<login-config>
  <auth-method>FORM</auth-method>
  <form-login-config>
    <form-login-page>/jsp/publico/Index.jsp</form-login-page>
    <form-error-page>/jsp/publico/errorauth.jsp</form-error-page>
    <form-default-page>/LoginCliente.do</form-default-page>
  </form-login-config>
</login-config>

Se pueden mencionar los siguientes Tags principales que pueden ser descritos en el web.xml

  • <login-config>: especifica el tipo de configuración de registro (login). Puede incluir los siguientes subelementos
    • <auth-method>: opcional
    • <realm-name>: opcional
    • <form-login-config>:opcional

  • <form-login-config>: Específica los recursos utilizados en el registro login basado en formularios. Debe contener los subelementos siguientes:

    <form-login-page> y <form-error-page> siendo los dos requeridos.

  • <form-login-page>: especifica el nombre de un recurso (html, página JSP, servlet) que solicita el nombre de usuario y la contraseña. Esta página debe cumplir los siguientes requisitos

    1. El formulario debe utilizar METHOD = “POST” y ACTION=”j_security_check”
    2. El campo de nombre de usuario debe denominarse j_username
    3. el campo de contraseña debe denominarse j_password.

  • <form-error-page>: Especifica el nombre de un recurso (HTML, JSP, servlet) a mostrar cuando el registro basado en el formulario no sea correcto.

  • <auth-constraint>: Especifica una lista de nombres de funciones (o roles) tratada colectivamente en un elemento <security-constraint>. Puede contener los siguientes subelementos <description> el cual es opcional y <role-name> (cero o más).

  • <role-name>: Un nombre utilizado para identificar una función o rol con el que un usuario autenticado se puede registrar. Es el mismo valor especificado en el método request.isUserInRole() para permitir la ejecución condicional de partes de un servlet a
    usuario con roles o funciones diferentes.
Por motivos de estructura similar a J2EE el formulario HTML tiene que tener la siguiente estructura de los campos j_username y j_password con el nombre de acción j_security_check como lo podemos ver en el ejemplo:

<form method="POST" action="j_security_check">
  <input type="text" name="j_username">
  <input type="password" name="j_password">
</form>

Esta forma de conexión usa codificación de base64, que puede exponer el nombre de usuario y clave a menos que sea con conexiones SSL.

Así los pasos que usamos son:
  1. Si el usuario no ha sido autenticado, le pide al usuario que de sus datos para tal acción recarga -a la página de ingreso (login) definida en el descriptor.

  2. Valida las credenciales del usuario contra la base de datos ya que es parte de nuestra aplicación.

  3. Determina si el usuario autenticado entonces está autorizado a ingresar al área solicitada según el descriptor.

Autorización

Una vez autenticado obtenemos el rol que posee y se verifica si puede asignar a los recursos solicitados, SecurityFilter tiene un archivo llamado securityfilter-config.xml el cual tiene centralizado todas las páginas que se puedan acceder según rol definidos en la aplicación (y también aparezcan en la base de datos, cual es nuestro repositorio).

De esta forma podemos administrar de manera fácil que rol tiene derecho de acceso a que Actions de Struts o JSP, según la lógica de negocio diseñada.

Ejemplo:

<security-constraint>
  <web-resource-collection>
  <web-resource-name>Pagina seguras Clientes</web-resource-name>
    <url-pattern>/jsp/cliente/*.jsp</url-pattern>
    <url-pattern>/RegistroObra.do*</url-pattern>
  </web-resource-collection>
  <auth-constraint>
    <role-name>cliente</role-name>
  </auth-constraint>
</security-constraint>


En este ejemplo podemos ver como se está asignando acceso a los JSP y un Action en particular únicamente a los usuarios que posean rol de “cliente”:

Además SecurtyFilter nos permite aun utilizar los métodos getRemoteUser(), isUserInRole(), y getUserPrincipal() para generar dentro de la aplicación reglas de seguridad a nivel de código Java.

Ventajas
  • La aplicación no necesita tener implementado el mecanismo de autenticación, sólo configurar los descriptores.
  • Con SecurityFilter la idea es empaquetar la seguridad dentro de la aplicación web, incluyendo la administración de roles, permitiendo generar un .war que puede liberarse en cualquier contenedor sin necesidad de configurar nada extra.


Bibliografía

iBATIS - The Beauty of Simplicity

When I was involved in a project for a Strength of Materials Certification Laboratory for my University, the solution included open source frameworks as Struts as presentation tier. but I had a doubt of connection tier.

The good point is Data model, tables, data, exist already, SQL queries I was going to be help for a student of last year, even more I could use some and I needed a simple solution, so EJB is discard immediately, Hibernate sound good (I reckon is the Object related tool on web today, but I need something simple and clean) then I remember I heard iBATIS as a easy-fast productivity SQL Mapper framework.

iBATIS gives all what I need, centralized management, easy of implement writing down all the SQL queries I need, linking them in a ResultSet (and JavaBean) and another doing the JSP interface (actually the html:form tags).



Thus the code could be reduce a lot, not doing those JDBC statement (mention above), besides I made a simple Java code to help writing down SQL maps and JavaBean (well, later on I knew there is Perl tool that do this better with DDL from the database: http://alxeg.narod.ru/ibatis/index.html . However my tool worked parsing , so it can read the name of the fields and make the JavaBean and XML; (this reduce even more the coding).

Another parameter to consider was
iBATIS born mature :) because after sun shows Jpetstore with better performance than Microsoft and release the interesting framework layer including SQL Maps and DAO.

Finally, the
iBATIS web scene was mature enough to get support for any issue on it. Plus the development team is still working hard enough to get more update version, solving some unexpected issues (you never know and it’s better to have some backup).
iBATIS mapped framework according to ibatis.apache.org, it has two important features, SQL maps and DAO -the last one we are going only mention because mapping is our main issue-

SQL Maps makes development much easier, and the maintenance too.

The Architecture of
iBATIS is:

Centralized SQL Mappings inside XML files, this way is easy to maintenance, flexible , scability, fix problems. Every java programmer knows how tedious is to code many times JDBC connection, making the code larger, more complex to read and worse to maintain and scability.



figure 1, taken from http://ibatis.apache.org/

architecture of iBATIS










<-- figure 2 --> data model of the example: entities (client, application_form, application_form_detail).

Here we configure the database properties (too redundant? :P)
database.properties:
driver=org.firebirdsql.jdbc.FBDriver
url=jdbc:firebirdsql:localhost/3050:C:/development/database/SAMPLEDBS.GDB
username=administrator
password=development2006


This file contains all the XML with SQL Maps
sql-map-config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig
PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-config-2.dtd">

<sqlMapConfig>

<properties resource="database.properties" />

<transactionManager type="JDBC">
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="${driver}"/>
<property name="JDBC.ConnectionURL" value="${url}"/>
<property name="JDBC.Username" value="${username}"/>
<property name="JDBC.Password" value="${password}"/>
</dataSource>
</transactionManager>

<sqlMap resource="TmpIndicesSQL.xml" />
<sqlMap resource="DetalleSolicitudSQL.xml" />

</sqlMapConfig>


An example of SQL Map, showing how to make ResultSet, INSERT, SELECT and UPDATE statement, with dynamic concatenation of condition in the statement (AND/OR in the WHERE).
DetalleSolicitudSQL.xml:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-2.dtd">

<sqlMap namespace="DetalleSolicitudSQL">

<cacheModel id="detallesolicitud_cache" type="MEMORY" >
<flushInterval hours="24"/>
<flushOnExecute statement= "insertDetalleSolicitud" />
<property name="reference-type" value="WEAK" />
</cacheModel>

<resultMap id="detallesolicitud_result" class="cl.unab.dicemat.utils.facade.DetalleSolicitud">
<result property="detsol_descripcion" column="x_detsol_descripcion" />
<result property="detsol_cantidad" column="x_detsol_cantidad" />
<result property="ens_cod_tipo" column="x_ens_cod_tipo" />
<result property="solcer_id" column="x_solcer_id" />
</resultMap>

<statement id="insertDetalleSolicitud">
INSERT INTO detalle_solicitud ( detsol_descripcion, detsol_cantidad, ens_cod_tipo, solcer_id )
VALUES ( #detsol_descripcion#, #detsol_cantidad#, #ens_cod_tipo#, #solcer_id# )
</statement>

<statement id="viewDetalleSolicitud" resultMap="detallesolicitud_result" cacheModel="detallesolicitud_cache">
SELECT detsol_descripcion AS x_detsol_descripcion,
detsol_cantidad AS x_detsol_cantidad,
ens_cod_tipo AS x_ens_cod_tipo,
solcer_id AS x_solcer_id
FROM
detalle_solicitud
</statement>

</sqlMap>

with a select to get a autoincrement key for Firebird database (also there is commented examples for PostgreSQL, in (2) you can get more code to different engines). This features that iBATIS has implemented for most DB engines, but still aren't 100% solve in the current time, however I could solved doing another query, leaving atomized and thread-safe. (I can show the example with Firebird). The good thing was the flexibility iBATIS has to go through this problem.

IndiceSQL.xml:

<resultMap id="tmpindices_result" class="cl.unab.dicemat.utils.facade.TmpIndices">
<result property="tabla" column="x_tabla" />
<result property="obra_id" column="x_obra_id" />
</resultMap>

<!--obra_id y tabla hacen solo de nombres genericos -->

<statement id="viewTmpIndices" resultMap="tmpindices_result" cacheModel="tmpindices_cache">
SELECT gen_id(GEN_SOLICITUDCERTIFICADO, 1) as x_obra_id,
rdb$$relation_id as x_tabla
FROM
rdb$$database
</statement>

SolicitudCertificadoAction.java snippet
The simple method dao.insertSolicitudCertificado(solicitudCertificadoDTO); insert the data in the javabean. Using beanutils commons.

SolicitudCertificadoForm.java, dynaform can be used, however I prefer to use normal JavaBean thus I can maintain the kind of data (int, String, Date).


Conclusion:

We finally are in the last stages of the project doing QA, the SQL Mapping was a success, I saved a lot of time though this framework. Getting a simpler and cleaner code, the performance of the application.


Bibliography:

iBATIS Home- ibatis.apache.org
iBATIS Wiki- http://opensource.atlassian.com/confluence/oss/display/IBATIS/Home
iBATIS mailing-list

Blog Archive

Disclaimer

The views expressed on this blog are my own and do not necessarily reflect the views of Oracle.