Wednesday, November 11, 2009

MANEJO DE 'REGEX EXPRESSIONS' EN JAVA

Las Expresiones Regulares (Regex) vienen a ser una forma sofisticada de hacer un Buscar & Reemplazar a una velocidad realmente impresionante. En el mundo Windows no tienen mucho sentido, después de todo allí casi todo va a base de clicks. Pero en el mundo Unix/Linux, en el que casi todo son ficheros de texto, son casi una herramienta imprescindible. No tan solo de cara al administrador, sino también de cara a cualquier otro programador que puede ver como las expresiones regulares le salvan la vida en más de una ocasión.

Java utiliza internamente dentro de API conocidas estas expresiones regulares, solo que nosotros no lo sabemos. Por ejemplo en las clases:
Split, StringTokenizer, Scanner

Cuando usas un Delimiter( "-" ) , estas dichas clases realizan un consulta y segmentación internamente utilizando ‘Regex’ o cuando uno hacer una cadena de conexión vía JDBC para la obtención de la URL, etc.

Aparte estas expresiones sirven también en diferentes lenguajes como para hacer la validación de formatos de: números, cadenas, email, etc.

Aquí una parte de lo preparado:

I. EL PUNTO: "." es el meta carácter por excelencia. Un punto representa cualquier caracter excepto nueva línea.

II. EL SIGNO DE DOLAR: "$" representa el final de la cadena de caracteres o el final de la línea, si se utiliza el modo multi-línea. No representa un carácter en especial sino una posición. Si se utiliza la expresión regular "\.$" el motor encontrará todos los lugares donde un punto finalice la línea, lo que es útil para avanzar entre párrafos.
..

…..

Para mayor detalle descargar la clase demo preparada desde:
Aquí.

Thursday, November 5, 2009

OBTENCIÓN DE UN ORACLE CURSOR DESDE JAVA

En muchas empresas acostumbran al momento de hacer un desarrollo de aplicaciones manejar la parte de persistencia (El acceso a los datos) , no mediante consultas SQL dentro de la misma aplicación, sino que prefieren manejarlas en base a Procedimientos Almacenados o Funciones que son invocadas desde la misma aplicación. Para este trabajo JAVA proporciona una muy buena clase y similar a PreparedStatement , en lo que respecta a su manipulación de datos, llamada CallableStatement.

En esta oportunidad mostraré como manejar, mediante un ejemplo, dicha clase CallableStatement para algo no muy común pero útil que es el llamado a un STORE PROCEDURE que internamente manejará un CURSOR, para la obtención datos de una Tabla en ORACLE y mediante JAVA obtendremos dichos datos en base a una ArrayList de un DTO (Data Transfer Object) , para cualquier manipulación posterior.

Para el ejemplo necesitaremos:

- Eclipse 3.4,
- Motor de datos Oracle 10g
- JDK 1.5 (Superior)
- classes12.jar
- DbVisualizer


I.- Crearemos en un SCHEMA de ORACLE, la tabla respectiva junto con los INSERTs de prueba (Podemos utilizar esta muy buena herramienta DbVisualizer para la creaciòn y manipulaciòn de bases de datos 'Para mi la mas completa'):

CREATE TABLE TB_CLIENTE( CODIGO INT,
TELEFONO VARCHAR2(30),
NOMBRES VARCHAR2(30),
APELLIDOS VARCHAR2(30),
DIRECCION VARCHAR2(50),
ESTADO VARCHAR2(10),
CONDICION VARCHAR2(30)
);

INSERT INTO TB_CLIENTE( CODIGO, TELEFONO, NOMBRES, APELLIDOS, DIRECCION, ESTADO, CONDICION ) VALUES( 1, '5214952 ', 'Ricardo ', 'Guerra ', 'Av.Naranjal 1029 Los Olivos ', 'Activo ', 'Aprobado' );
INSERT INTO TB_CLIENTE( CODIGO, TELEFONO, NOMBRES, APELLIDOS, DIRECCION, ESTADO, CONDICION ) VALUES( 2, '2222222 ', 'Percy ', 'Rojas ', 'Sucasa ', 'Activo ', 'Aprobado' );
INSERT INTO TB_CLIENTE( CODIGO, TELEFONO, NOMBRES, APELLIDOS, DIRECCION, ESTADO, CONDICION ) VALUES( 3, '43434354 ', 'Erick ', 'Arrieta Veliz ', 'Zarate ', 'Activo ', 'Aprobado' );
INSERT INTO TB_CLIENTE( CODIGO, TELEFONO, NOMBRES, APELLIDOS, DIRECCION, ESTADO, CONDICION ) VALUES( 4, '43434555 ', 'Rosa ', 'Zarate Aquino ', 'Los Montes 444 ', 'Inactivo ', 'Eliminado' );
INSERT INTO TB_CLIENTE( CODIGO, TELEFONO, NOMBRES, APELLIDOS, DIRECCION, ESTADO, CONDICION ) VALUES( 5, '33333333 ', 'Ruben Daniel ', 'Diaz Rodriguez ', 'Los Recuerdos 115 int 9 ', 'Inactivo ', 'Eliminado' );
INSERT INTO TB_CLIENTE( CODIGO, TELEFONO, NOMBRES, APELLIDOS, DIRECCION, ESTADO, CONDICION ) VALUES( 6, '3722736 ', 'Jose ', 'Perez Suarez ', 'Las Gardenias ', 'Activo ', 'Aprobado' );
INSERT INTO TB_CLIENTE( CODIGO, TELEFONO, NOMBRES, APELLIDOS, DIRECCION, ESTADO, CONDICION ) VALUES( 7, '65656565 ', 'Harold ', 'Pajuelo Reyes ', 'Los Monos 333 ', 'Inactivo ', 'Eliminado' );


II.- Creamos un ORACLE PACKAGE (CABECERA Y CUERPO) para contener al STORE PROCEDURE que tendrá en su interior al CURSOR, ya que necesariamente un CURSOR esta ligado a un ORACLE PACKAGE.

CREATE OR REPLACE PACKAGE PQ_DEMO AS

-- AUTOR : ADMINISTRADOR RICARDO GUERRA
-- CREACION : 14/08/2009 - 09:25:43 A.M.

-- Declaracion Global
TYPE cursorDinamico IS REF CURSOR;

-- PROCEDURE #1:
PROCEDURE SP_DEMO( msgValidacion OUT VARCHAR2, listaRegistros OUT PQ_DEMO.cursorDinamico );

END PQ_DEMO ;


CREATE OR REPLACE PACKAGE BODY PQ_DEMO IS

-- PROCEDURE #1:
PROCEDURE SP_DEMO( msgValidacion OUT VARCHAR2, listaRegistros OUT PQ_DEMO.cursorDinamico
) AS

--MENSAJE DE EXITO.
MSG_EXITO CONSTANT VARCHAR2(100) := 'Transaccion Exitosa.';

--MENSAJES DE ERROR.
MSG_ERROR1 CONSTANT VARCHAR2(100) := 'Se ejecuto una consulta sin estar conectado a la BD.';
MSG_ERROR2 CONSTANT VARCHAR2(100) := 'No se encontraron registros.';
MSG_ERROR3 CONSTANT VARCHAR2(100) := 'Se efectuo una operacion no valida sobre un cursor.';
MSG_ERROR4 CONSTANT VARCHAR2(100) := 'Se encontro un error la codifcacion PL/SQL.';
MSG_ERROR5 CONSTANT VARCHAR2(100) := 'Error durante la ejecucion del SP.(Other)';

BEGIN
--OBTIENE UNA LISTA DE REGISTROS.
OPEN listaRegistros FOR
SELECT c.CODIGO, c.TELEFONO, c.NOMBRES, c.APELLIDOS, c.DIRECCION, c.ESTADO, c.CONDICION
FROM TB_CLIENTE c;

msgValidacion := MSG_EXITO;
COMMIT;

--VALIDACION DE POSIBLES ERRORES.
EXCEPTION
WHEN NOT_LOGGED_ON THEN
msgValidacion := MSG_ERROR1;
DBMS_OUTPUT.PUT_LINE( MSG_ERROR1 );
ROLLBACK;
WHEN NO_DATA_FOUND THEN
msgValidacion := MSG_ERROR2;
DBMS_OUTPUT.PUT_LINE( MSG_ERROR2 );
ROLLBACK;
WHEN INVALID_CURSOR THEN
msgValidacion := MSG_ERROR3;
DBMS_OUTPUT.PUT_LINE( MSG_ERROR3 );
ROLLBACK;
WHEN PROGRAM_ERROR THEN
msgValidacion := MSG_ERROR4;
DBMS_OUTPUT.PUT_LINE( MSG_ERROR4 );
ROLLBACK;
WHEN OTHERS THEN
msgValidacion := MSG_ERROR5;
DBMS_OUTPUT.PUT_LINE( MSG_ERROR5 );
ROLLBACK;

--CLOSE listaRegistros.
CLOSE listaRegistros;

END SP_DEMO;

END PQ_DEMO ;


III.- En la aplicación demo JAVA preparada manejamos la conexión a ORACLE dinámicamente en base a una clase para multi-conexión de Motores de datos, administrada por un jdbc.properties donde se indica a que motor se desea conectar.

### DATOS CONEXION 'MySql' ###
jdbc_mysql_driverClassName = com.mysql.jdbc.Driver
jdbc_mysql_url = jdbc\:mysql\://localhost\:3306/DB_PLANTILLA
jdbc_mysql_username = root
jdbc_mysql_password = root

### DATOS CONEXION 'Postgres' ###
jdbc_postgres_driverClassName = org.postgresql.Driver
jdbc_postgres_url = jdbc\:postgresql\://localhost\:5432/DB_PLANTILLA
jdbc_postgres_username = postgres
jdbc_postgres_password = postgres

### DATOS CONEXION 'Oracle' ###
jdbc_oracle_driverClassName = oracle.jdbc.OracleDriver
jdbc_oracle_url = jdbc\:oracle\:thin\:@10.226.0.62\:1523\:DB_PLANTILLA
jdbc_oracle_username = oracle
jdbc_oracle_password = oracle

### 'motor_db_usado' => CAMPO EDITABLE PARA LA VALIDACION ###
### DE LA CONEXION A DIFERENTES BASES DE DATOS ###
### 1=MySql, 2=Postgres, 3=Oracle. ###
### IMPORTANTE: Tiene que estar el JAR respectivo dentro de la
aplicacion ###

motor_db_usado = 3


IV.- Creamos nuestro DTO (Data Transfer Object) llamado ClienteDTO para la manipulación de los datos orientada a objetos.

package org.java.bean;

/**
* ClienteResumenDTO objeto DTO para facil manejo de datos respectivos orientados a objetos.
*
* @author Ricardo Guerra
* @version v1.5 - 07-ago-2009
* @since V1.0
*/
public class ClienteDTO{

private int codigo;
private String nombres;
private String apellidos;
private String direccion;
private String telefono;
private String condicion;
private String estado;


// Constructores
public ClienteDTO(){
}

public ClienteDTO( int codigo, String nombres, String apellidos, String direccion, String telefono, String condicion, String estado ){
this.codigo = codigo;
this.nombres = nombres;
this.apellidos = apellidos;
this.direccion = direccion;
this.telefono = telefono;
this.condicion = condicion;
this.estado = estado;
}

public String getNombres(){
return nombres;
}

public void setNombres( String nombres ){
this.nombres = nombres;
}

public String getApellidos(){
return apellidos;
}


…..
…….


V.- Creamos nuestra clase TestOracle.java que nos permitirá hacer la consulta por medio del STORE PROCEDURE, obtener el mensaje de validación de respuesta y la lista de datos obtenida por medio del CURSOR, hacer el parseo y cargar la lista de Objetos (DTO) .

public class TestOracle{

private ManejoConexiones manejoConexiones = null;

//Construye ...
{
this.manejoConexiones = new ManejoConexiones();
}

/**
* @param argumentos
*/
public static void main( String... argumentos ){

TestOracle test = new TestOracle();

List listaDatos = new ArrayList();
listaDatos.clear();

//Consulta ...
listaDatos = test.buscarCursorOracle();

//Imprime ...
test.imprimeDatos( listaDatos );
}

/**
* buscarCursorOracle
* @return List
*/
private List buscarCursorOracle(){

CallableStatement cstm = null;
Connection conexion = null;
ResultSet rs = null;

ClienteDTO clienteDTO = null;
List listaClienteResumen = new ArrayList();

try{
Connection CONEXION = Conector.getConnection( Conector.getCibertec() );

/** Se ejecuta el StoreProcedure * */
conexion = CONEXION;
cstm = conexion.prepareCall( "begin PQ_DEMO.SP_DEMO( ?, ? ); end;" );

//Registro como parametro OUTPUT #1
cstm.registerOutParameter( 1, OracleTypes.VARCHAR );

//Registra el CURSOR como parametro OUTPUT #2
cstm.registerOutParameter( 2, OracleTypes.CURSOR ); //Obtiene la Lista del CURSOR en base a la posicion del parametro.

cstm.execute();

String parametro1 = (String)cstm.getString( 1 );
System.out.println( "Parametro OUTPUT #1: " + parametro1 );

rs = (ResultSet)cstm.getObject( 2 ); //Forma #1
//rs = ((OracleCallableStatement)cstm).getCursor( 2 ); //Forma #2

System.out.println( "Parametro OUTPUT #2: " + rs );

//Lleno el Objeto ...
while( rs.next( ) ){
clienteDTO = new ClienteDTO();

//Seteos en base a los obtenido en el Store Procedure.
clienteDTO.setCodigo( rs.getInt( "CODIGO" ) );
clienteDTO.setNombres( rs.getString( "NOMBRES" ) );
clienteDTO.setApellidos( rs.getString( "APELLIDOS" ) );
clienteDTO.setDireccion( rs.getString( "DIRECCION" ) );
clienteDTO.setTelefono( rs.getString( "TELEFONO" ) );
clienteDTO.setCondicion( rs.getString( "CONDICION" ) );
clienteDTO.setEstado( rs.getString( "ESTADO" ) );

//Agregando a la lista ...
listaClienteResumen.add( clienteDTO );
}

System.out.println( "TAMAÑO LISTA: " + listaClienteResumen.size() );
}
catch( Exception e ){
e.printStackTrace();
}
finally{
this.manejoConexiones.cerrarConexiones( rs, null, cstm, conexion );
}

return listaClienteResumen;
}

/**
* imprimeDatos
* @param listaClientes
*/
public void imprimeDatos( List listaClientes ){

System.out.println( "" );
System.out.println( "IMPRIMIENDO DATOS DE 'CLIENTES'" );
System.out.println( "-------------------------------" );

for( int i=0; i
ClienteDTO cliente = (ClienteDTO)listaClientes.get( i );

System.out.println( "" );
System.out.println( "CODIGO: " + cliente.getCodigo() );
System.out.println( "NOMBRES: " + cliente.getNombres() );
System.out.println( "APELLIDOS: " + cliente.getApellidos() );
System.out.println( "DIRECCION: " + cliente.getDireccion() );
System.out.println( "TELEFONO: " + cliente.getTelefono() );
System.out.println( "CONDICION: " + cliente.getCondicion() );
System.out.println( "ESTADO: " + cliente.getEstado() );
System.out.println( "" );
}
}


El mensaje de salida obtenido será este:

CONEXION ESTABLECIDA!!! oracle.jdbc.driver.OracleConnection@16930e2
Parametro OUTPUT #1: Transaccion Exitosa.
Parametro OUTPUT #2: oracle.jdbc.driver.OracleResultSetImpl@107077e
TAMAÑO LISTA: 8

IMPRIMIENDO DATOS DE 'CLIENTES'
-----------------------------------------------------

NOMBRES: Ricardo
APELLIDOS: Guerra
DIRECCION: Av.Naranjal 1029 Los Olivos
TELEFONO: 5214952
CONDICION: Aprobado
ESTADO: Activo

NOMBRES: Percy
APELLIDOS: Rojas
DIRECCION: Sucasa
TELEFONO: 2222222
CONDICION: 22222
ESTADO: Activo

NOMBRES: Erick
APELLIDOS: Arrieta Veliz
DIRECCION: Zarate
TELEFONO: 43434354
CONDICION: Aprobado
ESTADO: Activo


…..
…….


Para descarga del demo completo pulsar AQUÍ.

Sunday, October 25, 2009

SCJP 6 (Sun Certified Programmer for Java 6)

Sun Java Certification Program, es el programa de certificación mundial relacionada a la tecnología Java. Esta se enfoca en la certificación de personas en que desempeñan los roles en desarrollo y arquitectura en aplicación de software. Estas certificaciones acreditan el conocimiento y experiencia en el lenguaje Java. Por otro lado, Sun ofrece las siguientes certificaciones profesionales Java:

- Sun Certified Java Associate (SCJA)
- Sun Certified Java Programmer (SCJP)
- Sun Certified Java Developer (SCJD)
- Sun Certified Web Component Developer (SCWCD)
- Sun Certified Business Component Developer (SCBCD)
- Sun Certified Developer For Java Web Services (SCDJWS)
- Sun Certified Mobile Application Developer (SCMAD)
- Sun Certified Enterprise Architect (SCEA)

En esta oportunidad hablaremos sobre la certificación SCJP (Sun Certified Programmer for the Java Platform), Standard Edition 6. Este es un examen para programadores experimentados en la programación en el lenguaje Java. Esta certificación provee una clara evidencia en el entendimiento de estructura, sintaxis, etc., en la programación en el lenguaje y acredita el conocimiento en la creación de aplicaciones Java que corran en Escritorio y Servidor a nivel mundial usando Java SE 6.

Para la gente que este por dar el examen SCJP (Sun Certified Programmer for Java 6 Exam) , este es el libro que contiene todo lo necesario para una preparación por excelencia ya que contiene todos los temas al detalle:



El libro se llama 'Sun Certified Programmer for Java 6 Study Guide', esta en Ingles, muy bien detallado, con ejemplos, Quiz de prueba al final de cada capìtulo y esta dividido de la siguiente manera:

Temas:
---------
* Independientes:
Pag#1 (1 Hoja)
Pag#6 (1 Hoja)

* Contents:
Pag#15 - Pag#21 (6 Hojas)

* Cap#1: Declarations and Acces Control:
Pag#39 - Pag#122 (83 Hojas)

* Cap#2: Object Orientation:
Pag#123 - Pag#220 (97 Hojas)

* Cap#3: Assignments:
Pag#221 - Pag#324 (97 Hojas)

* Cap#4: Operators:
Pag#325 - Pag#364 (39 Hojas)

* Cap#5: Flow Control, Exceptios and Assertios:
Pag#365 - Pag#462 (97 Hojas)

* Cap#6: String, I/O, Formatting and Parsing:
Pag#463 - Pag#578 (115 Hojas)

* Cap#7: Generics and Collectios:
Pag#579 - Pag#698 (119 Hojas)

* Cap#8: Inner Classes:
Pag#699 - Pag#738 (39 Hojas)

* Cap#9: Threads:
Pag#739 - Pag#827 (88 Hojas)

* Cap#10: Threads:
Pag#828 - Pag#868 (40 Hojas)

II.- Capítulos Faltantes:

* Cap#11.pdf:
Pag#1 - Pag#15 (15 Hojas)

* Cap#12.pdf:
Pag#1 - Pag#14 (14 Hojas)

* Cap#13.pdf:
Pag#1 - Pag#17 (17 Hojas)

* Cap#14.pdf:
Pag#1 - Pag#22 (22 Hojas)

* Cap#15.pdf:
Pag#1 - Pag#8 (8 Hojas)

* Cap#16.pdf:
Pag#1 - Pag#6 (6 Hojas)

* Cap#17.pdf:
Pag#1 - Pag#19 (19 Hojas)

* Cap#18.pdf:
Pag#1 - Pag#11 (11 Hojas)

TOTAL HOJAS A IMPRIMIR: 934 Hojas


Para descargar El Libro para la Certificación Java SCJP 6 pulsar:
AQUÌ.

Para descargar El Libro OCP Java SE 6 Programmer Practice Exams pulsar:
AQUÌ.

Luego de leer todo el El Libro para la Certificación Java SCJP 6 a conciencia, aquí comparto estos SIMULADORES del examen, para que uno se pueda probar antes de rendir el dicho exàmen de certificación. Los Simuladores pertenecen a las entidades:

- Simulador 'TechFaq360'
- Simulador 'Sybex'
- Simulador 'Whizlabs'
- Simulador 'KillTest'

Para descargarlos pulsar: AQUI.

Friday, October 23, 2009

MULTI MANEJADOR JAPPLET - JFRAME (SIMULTANEO)

Esta es una solución en JAVA para un problema muy común que se da cuando trabajamos aplicaciones J2SE Desktop y que por x motivos nos se requiere que este colgada en un navegador.

Recordemos que en J2SE uno puede trabajar con AWT y SWING en el desarrollo de aplicaciones Desktop y a su vez crear dichas aplicaciones como JFRAMES, si se requiere que la aplicación a desarrollar corra en la red LAN y o también desarrollarlas como JAPPLET para que dicha aplicación este embebida en un navegador. Bueno una solución a este problema común en los desarrolladores es que se tenga dos proyectos idénticos, pero orientados uno a cada ambiente (Uno con JFRAME y otro con JAPPLET).

La solución a presentar elimina esa tendencia, ya que permite su manejo de ambos ambientes en una misma aplicación. Que quiero decir, que permite que ya no se desarrolle dos sino solo una aplicación y que esta corra tanto como aplicación Desktop (JFRAME) y como JAPPLET.

El ejemplo a mostrar continuación es algo simple pero que da una plantilla inicial para un desarrollo, que a la larga permitirá que dicha solución corra en ambos ambientes.

Ejemplo:
El árbol internamente del comprimido adjuntado es el siguiente:



- Importante.txt: Explica a todo el contenido del comprimido y de la solución.
- Fuentes Demo en Eclipse: Fuentes de la solución (Plantilla Inicial) en Eclipse.
- MultiManejadorJAppletJFrame.jar: .Jar dinámico que al dar doble click levanta la aplicación Desktop (JFRAME).
- Index_MultiManejador.html: Navegador que posee embebido un JAPPLET que es cargado del mismo MultiManejadorJAppletJFrame.jar.

Demo en 'JFRAME':

Demo en 'JAPPLET':


Para descargar MultiManejadorJAppletJFrame pulsar:
AQUÌ.

Thursday, October 22, 2009

LECTURA DE FICHEROS CON 'JAVA.UTIL.SCANNER'

El otro día me encontré una clase JAVA bien interesante, se llama java.util.Scanner y buscando su significado supe que utiliza comúnmente para una scanero de ficheros línea por línea y obtención de sus datos, tiene bastante métodos interesantes y la verdad su manejo me trajo a la mente la clase java.util.StringTokenizer ya que trabaja casi idénticamente solo que java.util.Scanner aparece en JAVA en la versión 1.5. Aquí muestro un ejemplito en donde leo un Fichero línea por línea y sus datos separados por el símbolo "–" me permiten diferenciar cada dato y con esto amarrar los datos a un objeto usuario para hacerlo mas interesante el ejemplo y de paso orientar a objetos el demo. El código es el siguiente:

//Test_Scanner.java

import java.io.File;
import java.io.IOException;
import java.util.Scanner;

/**
* @author: cguerra.
* @clase: Test_Scanner.java
* @descripción: descripción de la clase.
* @author_web: http://frameworksjava2008.blogspot.com -
* http://viviendoconjavaynomoririntentandolo.blogspot.com
* @author_email: cesarricardo_guerra19@hotmail.com.
* @fecha_de_creación: 22-10-2009.
* @fecha_de_ultima_actualización: 22-10-2009.
* @versión: 1.0
*/
public class Test_Scanner{

/**
* @param args
* @throws IOException
*/
public static void main( String... argumentos ) throws IOException{

Test_Scanner scanner = new Test_Scanner();
scanner.manejoScanner();
}

/**
* manejoScanner
*/
public void manejoScanner(){
try{
File archivo = new File( "C:\\MiArchivo.txt" );
Scanner lectorLinea = new Scanner( archivo );
Scanner lectorDatos = null;
Usuario usuario = null;

for( ; lectorLinea.hasNext(); ){

//Obtiene las lineas del 'Fichero'.
String linea = lectorLinea.nextLine();
//Escanea cada linea del 'Fichero'.
lectorDatos = new Scanner( linea ); lectorDatos.useDelimiter( "-" );

for( ; lectorDatos.hasNext(); ){

String codigo = ( lectorDatos.next() );
String nombres = ( lectorDatos.next() );
String apellidos = ( lectorDatos.next() );
String edad = ( lectorDatos.next() );
String dni = ( lectorDatos.next() );

Usuario = new Usuario(
Integer.parseInt( codigo ),
nombres,
apellidos,
Integer.parseInt( edad ),
dni );

//Crea un Nuevo Usuario.
System.out.println( "" );
System.out.println( "Codigo: " + usuario.getId() );
System.out.println( "Nombres: " + usuario.getNombres() );
System.out.println( "Apellidos: " + usuario.getApellidos() );
System.out.println( "Edad: " + usuario.getEdad() );
System.out.println( "Dni: " + usuario.getDni() );
System.out.println( "" );

}
}
}
catch( IOException e ){
e.printStackTrace();
}
catch( Exception e ){
e.printStackTrace();
}
}
}


//Usuario.java

import java.io.Serializable;

/**
* @author: cguerra.
* @clase: Usuario.java
* @descripción: descripción de la clase.
* @author_web: http://frameworksjava2008.blogspot.com -
* http://viviendoconjavaynomoririntentandolo.blogspot.com
* @author_email: cesarricardo_guerra19@hotmail.com.
* @fecha_de_creación: 22-10-2009.
* @fecha_de_ultima_actualización: 22-10-2009.
* @versión: 1.0
*/
public class Usuario implements Serializable{

private static final long serialVersionUID = 936463798820971716L;

private int id;
private String nombres;
private String apellidos;
private int edad;
private String dni;

//Constructores ...
public Usuario(){
}

public Usuario( int id, String nombres, String apellidos,
int edad, String dni ){
this.id = id;
this.nombres = nombres;
this.apellidos = apellidos;
this.edad = edad;
this.dni = dni;
}

public int getId(){
return id;
}

public void setId( int id ){
this.id = id;
}

public String getNombres(){
return nombres;
}

public void setNombres( String nombres ){
this.nombres = nombres;
}

public String getApellidos(){
return apellidos;
}

public void setApellidos( String apellidos ){
this.apellidos = apellidos;
}

public int getEdad(){
return edad;
}

public void setEdad( int edad ){
this.edad = edad;
}

public String getDni(){
return dni;
}

public void setDni( String dni ){
this.dni = dni;
}

public static long getSerialVersionUID(){
return serialVersionUID;
}

}

//MiArchivo.txt
001-Cesar Ricardo-Guerra Arnaiz-26-41816133
002-Catherine Magaly-Cotrina Vasquez-24-49866233

Sunday, October 18, 2009

ACTIVAR Y DESACTIVAR 'ASSERT' EN ECLIPSE

Algo raro y común que sucede, cuando se desea trabajar con ASSERT en ECLIPSE es que por defecto no esta habilitado y la pregunta es como habilitarlo ???. Aqui la soluciòn:

Windows -> Preferences -> Java -> Installed JREs.

Luego selecciona tu JDK y click el boton Edit y en el textfield "Default VM Arguments" agregar los còdigos siguientes, dependiendo como se desee trabajar:

-ea
Activa las 'Aserciones' de mi programa.

-da
Desactiva Las 'Aserciones' de mi programa.

-ea:class
Activa las 'Aserciones' de mi programa, pero sólo en la clase class.

-da:class
Desactiva las 'Aserciones' de la clase class.

-ea:package...
Activa las 'Aserciones' de mi programa; pero sólo en el paquete package.

-da:package...
Desactiva las 'Aserciones' del paquete package.

Friday, October 16, 2009

LABELED & UNLABELED EN BUCLES

Un gran aporte que da Java 1.6 es el manejo de Labels por cada ‘For’ utilizado, estos Labels son etiquetas que están directamente relacionadas a cada ‘For’ y la gran ventaja que te da es la facilidad de poder hacer un Break or Continue de un ‘For’ anidado Hijo a Otro ‘For’ que esta como Padre. El manejo es de la siguiente forma:

public class Test{

//Descomentar el ejemplo que se quiera ejecutar.
public static void main( String… args ){
Test test = new Test();
test.forUnLabeled (); //Habilitar el 1er ejemplo.
//test.forLabeled (); //Habilitar el 2do ejemplo.
}

/**
* forUnLabeled se muestra un For anidado simple.
*/
public void forUnLabeled(){

String cadena = "Ricardo X Guerra";
String newCadena = "";

//Forzando un bucle infinito.
for( int i=0; i Character caracter_01 = (Character)cadena.charAt( i );
newCadena += caracter_01;

System.out.println( "'FOR' [PAPA]==>: " + caracter_01 );

if( caracter_01 == 'X' ){

for( int j=10; j>=0; j-- ){
System.out.println( "'FOR' [HIJO]==>: " + j );
}
}
}
}

/**
* forLabeled se muestra un For anidado con una Etiqueta (Labeled) en su interior que
* esta asignada un cada 'For', permitiendo con esto desde un 'For' hijo hacer
* un Break a un 'For' Padre.
*/
public void forLabeled(){

String cadena = "Ricardo X Guerra";
String newCadena = "";

TagForPapa: //Etiqueta del 1er 'For'
//Forzando un bucle infinito.
for( int i=0; i Character caracter_01 = (Character)cadena.charAt( i );
newCadena += caracter_01;

System.out.println( "'FOR' [PAPA]==>: " + caracter_01 );

if( caracter_01 == 'X' ){

TagForHijo: //Etiqueta del 2do 'For'
for( int j=5; j>=0; j-- ){
System.out.println( "'FOR' [HIJO]==>: " + j );
}

break TagForPapa; //Manda a parar el 1er 'For' desde el 2do 'For'.
}
}
}


MANEJO BUCLE 'FOR' COMO 'WHILE'.

Java te da la verdad muchas ventajas a comparación de otros lenguajes de programación, una de ella es el trabajar los bucles de distintas maneras una de ellas y de la que hablaré a continuación es sobre el manejo de un bucle For pero trabajado de una forma distinta a la comúnmente conocida ya que un For lo trabajar para iterar: cadenas, arrays, listas, etc pero siempre como un limitante en su interior peroahora vamos a ver una forma distinta de trabajar el For sin dicho limitante, un trabaja que normalmente esta destinado a un While o a un Do While. El manejo es de la siguiente manera:

public class Test{

//Descomentar el ejemplo que se quiera ejecutar.
public static void main( String… args ){
Test test = new Test();
test.forWhileIliminado(); //Habilitar el 1er ejemplo.
//test.forWhileLimitado(); //Habilitar el 2do ejemplo.
}

/**
* forWhileIliminado aqui se muestra el manejo de un FOR/WHILE Ilimitado, ya que dicho For iterará infinitamente, porque no tiene una confición de Stop en su interior.
*/
public void forWhileIliminado(){

int contador = 0;

//Forzando un bucle infinito.
for( ; ; ){

contador += 1;

System.out.println( "CONTANDO ... " + contador );
}
}

/**
* forWhileLimitado aqui se muestra el manejo de un FOR/WHILE limitado, ya que en dicho For estamos
* condicionando un toque que es '654321' y si se llega a ese numero el Bucle
* para ( break,System.exit( 0 ), return ) sino continua su recorrido infinito
* (continue) .
*/
public void forWhileLimitado(){

int contador = 0;

//Forzando un bucle infinito.
for( ; ; ){

contador += 1;

if( contador == 654321 ){
System.out.println( "EL 'CONTADO' LLEGO A SU [FIN] EN: " + contador + " ...!!! " );
break; //Parar el 'LOOP'.
//System.exit( 0 ); //Parar el 'LOOP'.
//return; //Parar el 'LOOP'.
}
else{
System.out.println( "CONTANDO ... " + contador );
continue; //Continuar el 'LOOP'.
}
}

}

}

Thursday, October 15, 2009

JAVA REFLEXION

Hace unos días estuve indagando en el manejo de interno que comúnmente los Frameworks de JAVA utilizan y me tope con el tema de Reflexion. Este tema de Reflexion. es uno de los temas más avanzados que JAVA y su programación orientada a objetos maneja, la reflexión es comúnmente utilizada cuando se quiere examinar o modificar en tiempo de ejecución el comportamiento de las aplicaciones. Por ejemplo, sabiendo el nombre de una clase, podríamos saber:

Propiedades, campos, constructores, métodos, clases, interfaces, etc.

Este es un concepto que permite la programación dinámica, es como cuando uno obtiene la metadata de una tabla, pero en este caso es la metadata de una clase.

Se puede instanciar objetos, solo con saber el nombre de la clase, o ejecutar sus métodos en tiempo de ejecución.

El demo presentando preparado es una clase utilitaria que maneja el concepto de un POJO, esta clase brinda mediante métodos de acceso una seria de métodos como estos:

• public Method[] getArrayMetodos( Class claseProcesar ) ...
• public Method[] getArrayMetodos( String rutaClaseProcesar ) ...
• public Class[] getArrayInterfaces( Class nombreClaseProcesar ) ...
• public Class[] getArrayInterfaces( String rutaClaseProcesar ) ...
• public Field[] getArrayCamposDeclarados( Class nombreClaseProcesar ) ...
• public Field[] getArrayCamposDeclarados( String rutaClaseProcesar ) ...
• public String getClasePadre( String rutaClaseProcesar ) ...
• public String getClasePadre( Class nombreClaseProcesar ) ...
• public String getClasePadre( String rutaClaseProcesar ) ...
• public String getRutaPaquete( Class nombreClaseProcesar ) ...
• etc ...


Para descargar el demo pulsar:
AQUÌ.

Friday, October 9, 2009

LIBERACIÓN DE MEMORIA CON JAVA Y EL GARBAGE COLECTOR

Estudiando un día mi libro de certificación llegue al tema del manejo del Garbage Colector en JAVA y encontré temas muy importantes e interesantes que no sabía como que el Garbage Colector uno no puede ser forzado a pasar y liberar memoria, sino que cuando uno cuando en su aplicación genera X procesos que son muy pesados la memoria puede incrementarse a tal punto que le puede aparecer una Excepcion [java.lang.OutOfMemoryError] refiriéndose que ya no hay memoria suficiente y automaticamente tu aplicación se cuelga, para ello este método que acontinuación implemento puede ser llamado. Dicho ejemplo muestra un simple Test, en el que se imprime el total de memoria que se maneja al inicio, el total de memoria libre que queda luego de ejecutar un 'For' GIGANTE y el total de memoria que queda luego de ejecutar el método de liberacion de memoria que hace una solicitud a la JVM, para que el Garbage Colector pase:


import java.sql.Date;

/**
* @author: Ricardo Guerra.
* @clase: TestGarbageColector.java
* @descripción: Clase utilizada para probar el manejo del Garbage Colector en casos que las aplicaciones
* consuman mucha memoria.
* @author_web: http://frameworksjava2008.blogspot.com
* http://viviendoconjavaynomoririntentandolo.blogspot.com
* @author_email: cesarricardo_guerra19@hotmail.com.
* @fecha_de_creación: 05-08-2009.
* @fecha_de_ultima_actualización: 20-03-2009.
* @versión: 1.0
*/
public class TestGarbageColector{

/**
* @param args
*/
public static void main( String[] args ){
TestGarbageColector test = new TestGarbageColector();
test.testGarbageColector();
}

/**
* testGarbageColector Método que prueba un incremento de memoria para ver el manejo de la
* liveracion de esta al solicitar a la 'JVM' el 'GC'.
*/
public void testGarbageColector(){

Date fecha = null;

for( int i=0; i<1000000; i++) {
fecha = new Date( 10, 10, 2009 );
fecha = null;
}

//Solicitamos a la 'JVM' el 'GC', para liverar memoria.
this.getSolicitaGarbageColector();
}

/**
* getSolicitaGarbageColector Método que invoca al Garbage Colector( NO LO FUERZA a venir,
* envia una solicitud a la JVM para su proceso..!!! )
*
*/
public void getSolicitaGarbageColector(){

try{
System.out.println( "********** INICIO: 'LIMPIEZA GARBAGE COLECTOR' **********" );
Runtime basurero = Runtime.getRuntime();
System.out.println( "MEMORIA TOTAL 'JVM': " + basurero.totalMemory() );
System.out.println( "MEMORIA [FREE] 'JVM' [ANTES]: " + basurero.freeMemory() );
basurero.gc(); //Solicitando ...
System.out.println( "MEMORIA [FREE] 'JVM' [DESPUES]: " + basurero.freeMemory() );
System.out.println( "********** FIN: 'LIMPIEZA GARBAGE COLECTOR' **********" );
}
catch( Exception e ){
e.printStackTrace();
}
}
}


El resultado en CONSOLA obtenido es el siguiente:


********** INICIO: 'LIMPIEZA GARBAGE COLECTOR' **********
MEMORIA TOTAL 'JVM': 4194304
MEMORIA [FREE] 'JVM' [ANTES]: 1137312
MEMORIA [FREE] 'JVM' [DESPUES]: 3749208
************ FIN: 'LIMPIEZA GARBAGE COLECTOR' ***********

Thursday, October 8, 2009

DBHelper v2.0

Pensando en los diferentes problemas de sintaxis que a diario se presentan cuando uno trabaja en el Àrea de Sistemas como: P, AP, DBA en la creaciòn y manipulaciòn de datos en diferentes Motores de Datos, creè DBHelper v2.0.

DBHelper v2.0 es una aplicación hecha en JAVA SWING con la finalidad de brindar ayuda a los desarrolladores, DBA's, etc. en lo que respecta a la sintaxis para la construcción de:

Stores Procedure, Fuction, View, Trigger, Package, Sequence.

En los diferentes y muy conocidos Motores de Datos:

Oracle, MySql, Postgres, SqlServer.

Ya que dicha sintaxis varìa según el Motor de Datos utilizado, en lo que respecta a delaraciòn de variables, nombres de funciones internas, asignaciones, etc. Ya que todos los Motores de Datos estàn orientados a un mismo Lenguaje de Programaciòn como base que es el SQL y de ese ya nacen los personalizados que varian un poco como son:

PLSQL, TRANSACSQL, PGSQL, etc.

DB_JavaHelper esta orientado a ayudar en lo que a sintaxis por Motor de Datos respecta y muestra tambien como probar cada uno, dando una plantilla base para cada Motor de Datos para cada procediento a realizar.



Requisitos Previos: DB_JavaHelper, esta creado para trabajar con JAVA 1.6 y es IMPORTANTE el NO cambiar los nombres de las carpetas y ejecutables encontrados dentro del comprimido. Simplemente se descomprime el .zip, se guarda un una ruta respectiva y se crea un acceso directo al ejecutable (DB_JavaHelper.jar).

- NOMBRE CARPETA RAIZ = DB_JavaHelper
- NOMBRE CARPETA_SCRIPT = Script
- NOMBRE EJECUTABLE = DB_JavaHelper.jar

Desde DB_JavaHelper tambien se puede descargar los Script por BD, los cuales sirvieron de base para las plantillas mostradas en los ejemplos.

Para descargar DB_JavaHelper pulsar:
AQUÌ.


Sunday, September 13, 2009

Acceso a Recursos desde un aplicaciòn Java J2SE

Normalmente cuando desarrollamos una aplicaciòn JAVA desktop en SWING o AWT hay inconvenientes para poder acceder a las imagenes, ficheros, etc.

La soluciòn es la que se muestra en la gràfica.


Se tendrìa que crear un SourceFolder llamado Imagenes, en donde se crearia un paquete que contenga una ruta similar a la mostrada y que dentro estarìan: imagenes, ficheros, etc. Estos recursos serìan accedidos y reconocidos facilmente codificando desde tu clase JAVA de la siguiente manera.

URL url_lmagen = ClassLoader.getSystemResource( org\\formatos\\jpg\\Nombre_Imagen.jpg );

Monday, August 31, 2009

Multiconexiones JDBC

Las clases conexion en una aplicacion JAVA es la clave para que tu aplicacion JAVA acceda y se conecte a un servidor de base de datos. Para ello se realiza clases que mediante Driver JDBC se conectan. Muchas veces los desarrolladores caen en la necesidad de crear muchas conexiones que se encuentran regadas en difrentes partes de la aplicacion, esto en realidad no es lo optimo pero se hace muchas veces. Lo mejor es tener una clase que administre las conexiones a las base de datos. El ejemplo que mostraremos continuacion realiza esto y mucho mas. Este consta que un ECLIPSE Dinamic Project que posee un paquete de conexion (org.java.conexion), que maneja administra las conexiones a diferentes motores de datos SIMULTANEAMENTE( MySql, SqlServer, Oracle, Postgres ). Simplemente con cambiar un parametro en el fichero .properties.

Dentro de la aplicacion se encontrarà todas las librerias JDBC necesarias y tambien se encontrara el fichero ScriptBD.txt con los script de prueba para cada motor de datos.


Para descargar la aplicacion demo de multiconexiones JDBC pulsar AQUI.

CONFIGURACION JDBC PARA SQL SERVER 2005 EXPRESS

En esta oportunidad mostrae la configuración para crear una conexión JDBC entre una aplicación JAVA con el respectivo servidor SQL Server 2005 Express.

Los requerimientos previos y el software necesario son los siguientes:

Requerimientos Previos:>

- NetFramework v4.0.exe (DESCARGAR.)
- Windows Installer v4.5.exe (DESCARGAR.)

Herramienta SQL Sever (DESCARGAR AMBOS.):

- SQL Server 2005 Express.exe.
- SQL Server Manager Studio 2005 Express.msi

Para acceder a este motor de datos vía una aplicación JAVA JDBC, se debe de realizar lo siguiente:

Descargar los drivers de conexión desde AQUI.:

- sqljdbc.jar
- sqljdbc4.jar
- mssqlserver.jar
- msbase.jar
- msutil.jar
- jtds-1.2.2.jar

Acceder a tu herramienta de desarrollo ECLIPSE y crear un proyecto Dinamic Web y en la carpeta lib ingresar los .Jars de conexión descargados. Luego, creamos una clase .java para la conexión con los motores de datos SQL Server 2000 y SQL Server 2005, aquí comparto mi clase que desarrolle:

package org.java;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;

public class ConexionSQLServeJDBC{

private Connection conexion = null;
private final String url = "jdbc:microsoft:sqlserver://";
private final String servidor = "localhost\\SQLEXPRESS";
//"192.168.1.33"; //"LOCALHOST"; //"LOCALHOST\\SQLEXPRESS SQLSERVER2000";
private final String puerto = "1433";
private final String baseDatos = "DEMODB";
private final String usuario = "sa";
private final String password = "sql";
private final String metodo = "cursor"; //direct - cursor;

//Constructor.
public ConexionSQLServeJDBC(){
}

//Levanta la Aplicacion.
public static void main( String[] args ) throws Exception{
ConexionSQLServeJDBC conexionJDBC = new ConexionSQLServeJDBC();
conexionJDBC.propiedadesDataBase();
}
/**
* getConnectionUrl
* @return String
*/
private String getConnectionUrl(){

/*
* El driver de Microsoft NO funciona con "servidor\instancia". Para solucionar el
* tema, debes indicar la direccion IP del servidor + el puerto de la instancia.
*/

//String SQL = ( this.url + this.servidor + ":" + this.puerto + ";databaseName=" + this.baseDatos + ";" + "selectMethod=" + this.metodo + ";" );

String SQL = ( this.url + this.servidor + ":" + this.puerto + ";databaseName=" + this.baseDatos + ";" );

System.out.println( "Cadena CONEXION JDBC: " + SQL );

return SQL;
}
/**
* getConnection
* @return Connection
*/
private Connection getConnection(){
try{
Class.forName( "com.microsoft.jdbc.sqlserver.SQLServerDriver" );
this.conexion = java.sql.DriverManager.getConnection( this.getConnectionUrl(), this.usuario, this.password );

if( this.conexion != null ){
System.out.println( "Conexión .... OK" );
}
else{
System.out.println( "Conexión .... NOK" );
}
}
catch( Exception e ){
e.printStackTrace();
System.out.println( "Error de seguimiento en 'getConnection()': " + e.getMessage() );
}
return this.conexion;
}

/**
* propiedadesDataBase
*/
public void propiedadesDataBase(){

DatabaseMetaData metaData = null;
ResultSet rs = null;
int contador = 0;

try{
this.conexion = this.getConnection();

if( this.conexion != null ){
metaData = this.conexion.getMetaData();

System.out.println( "" );
System.out.println( "****** INFORMACION DEL CONTROLADOR JDBC ******" );
System.out.println( " - NOMBRE: " + metaData.getDriverName() );
System.out.println( " - VERSION: " + metaData.getDriverVersion() );
System.out.println( "" );
System.out.println( "****** INFORMACION DE BASE DE DATOS ******" );
System.out.println( " - NOMBRE: " + metaData.getDatabaseProductName() );
System.out.println( " - VERSION: "+ metaData.getDatabaseProductVersion() );
System.out.println( "" );
System.out.println( " - BASES DE DATOS ACTIVAS: " );

rs = metaData.getCatalogs();

while( rs.next() ){
contador += 1;
System.out.println( " BD #" + contador + ": " + rs.getString( 1 )
);
}
this.cerrarConexiones( this.conexion, rs );
}
else{
System.out.println( "Error: No hay ninguna Conexión SQL Activa" );
}
}
catch( Exception e ){
e.printStackTrace();
}
}
/**
* cerrarConexiones
* @param conexion
* @param rs
*/
private void cerrarConexiones( Connection conexion, ResultSet rs ){
try{
if( conexion != null ){
conexion.close();
}
if( rs != null ){
rs.close();
}
}
catch( Exception e ){
e.printStackTrace();
}
}
}

Thursday, July 23, 2009

Sintaxis JAVA & JAVADOC 'Standar'

El otro día indagando en las opciones de esta maravillosa Ide de desarrollo que es el Eclipse v3.3, ya que por lo que conozco se que es, en la mayoría de sus opciones, personalizadle, la solución para aplicar un forma estándar en lo que respecta la creación de mis métodos, clases, declaraciones, iteradores, etc. Cuando digo aplicar un estándar me refiero a una sintaxis personalizada (espacios entre declaración y variable, distancia entre métodos y declaraciones, la llaves estén pegadas o no pegadas a la clase o método, etc. ) y al igual que para las sintaxis netamente de la programacion de JAVA, necesitaba una para ya no están creando los JAVADOC para cada método o get y set, etc. Buscando la solución la encontré Eclipse tiene opciones para la personalización de todo esto que he hablado, simplemente entrando a:
(Windows/Preferences/Java/Code Style).

Dentro encontraran estas 2 opciones:

I.- Code Formatter (o Formatter):
En esta opciones uno puede crear un perfil de formato, que quedara registrado en el comboBox y que dentro de dicho perfil se crearan desde una interfase a base de taps toda la personalización en cuando al código de programación que desees para luego guardar en un XML todos tu profile. También permite la importación de un XML que anteriormente hayas guardado.

II.- Code Template:
En esta opciones uno puede importar un XML donde se encuentre personalizado todo los JAVADOC, para cada caso que se indica en las opciones Commets y Code.

La funcionalidad esta para la sintaxis JAVA es aplicada cuando generes código o crees clases, etc. utilizando la herramienta (ECLIPSE) misma o sino cuando pegues en el paquete una clase externa o código externo y simplemente pulsado:
(Crtl + Shift + F), todo el código será transformado según la sintaxis que hayas definido en tu XML importado o creado.

Aquí muestro dos imágenes, una de cada opción:

Code Formatter (ó Formatter)


Code Template


Para mayor detalle descargar los 'XML' con los Standares aplicados y listos para ser importados pulsando: AQUI.

Tuesday, June 2, 2009

Eclipse ShortCuts

Tratando de tener un mejor y màs manejo de esta excelente IDE de desarrollo. Posteo en esta oportunidad la lista de ShortCuts que maneja Eclipse junto con todas las demas IDEs màs potentes como WebsPhere, Red Hat Developer Studio, MyEclipse, JBoss Developer Studio, Etc. Ya que poseen como base a Eclipse. La lista de Eclipse ShortCuts es:

Explicaciòn.

Monday, May 4, 2009

Descargador Videos Youtube en JAVA.

Aqui les comparto un demo creado con la finalidad de generar un Descargador de Video de 'Youtube' en JAVA. El demo esta desarrollado en base a Hilos.

Para el manejo simplemente en el textField ingresar la URL del video de Youtube deseado y pulsar el boton descargar. Dependiendo del tamaño del video la aplicacion como que se colgara, pero la razon es que se genero un hilo de descarga. Al finalizar la descarga en mostrara en el TextArea la ruta donde se guardo el video descargado y un mensaje de conformidad.

Los videos descargado bajaràn en formado .Flv en la ruta:
C:\VideosDescargados y para visualizarlos se tendra que descargar el reproductor: Riva FLV PLAYER v2.0.

Dentro del comprimido se encontrara un .zip con el codigo fuente de la aplicacion y un .jar que es el ejecutable ya compilado y funcionando.

Para descargar la aplicaciòn demo pulsar:
Aquì.

Saturday, May 2, 2009

Encriptaciòn, Criptografia y Firmas Digitales en JAVA.

Hola como estan, en esta oportunidad postearè sobre Encriptaciòn, Criptografia y Firmas Digitales en JAVA , por ese motivo estoy compartiendo un par de clases especiales ('ManejoEncriptacion.java') para el manejo de encriptacion y desencriptacion de datos y manejo de firmas digitales, utilizando los algoritmos 'SHA1, MD5, BASE64, CIPHER, SHA1PRNG, SUNJCE, BLOWFISH' . Esta muy bien detalla y ordenada. El manejo de este par de clases seria simplemente instanciandolas y accediendo a los mètodos respectivos, segun convenga. He creado dentro de cada clase un mètodo "main" que muestra la forma como llamar a los mètodos para ver su funcionamiento y lo que imprime al ejecutarce dichas clases:

I.- Ejecuciòn clase: 'ManejoEncriptacion.java' Al ejecutarce esta clase se muestran la aplicaciòn de los algoritmos respectivos, ya antes comentados.


/*******************************************************************************/
Dato Original a Encriptar: Cesar Ricardo Guerra Arnaiz ==> 'JAVAMAN'

- Dato Encriptado utilizando 'SHA1': 963B634E2A2A74399D521545372C590640F6328FF615
- Dato Encriptado utilizando 'MD5': 9B47DE66E257144C9A6C4BA463DC673C1C67
- Dato Encriptado utilizando 'BASE64': Q2VzYXIgUmljYXJkbyBHdWVycmEgQXJuYWl6ID09PiAnSkFWQU1BTic=
- Dato Encriptado utilizando 'CIPHER': rqYOA80r41UjlAdaIq32MSW8ZBzh1ue/qUux9Z9TvDFclqWrG8e55mTxVE9ohJ2u

- Dato Comparado Existente 'SHA1': true
- Dato Comparado Existente 'MD5': true
- Dato Desencryptado utilizando 'BASE64': Cesar Ricardo Guerra Arnaiz ==> 'JAVAMAN'
- Dato Desencryptado utilizando 'CIPHER': Cesar Ricardo Guerra Arnaiz ==> 'JAVAMAN'
/*******************************************************************************/


II.- Ejecuciòn clase: 'ManejoCriptografia_FirmasDigitales.java'
Esta clase al ejecutarce guardara en la ruta: C:\\Encriptacion\\
4 archivos '.txt' ( CriptografiaPrivada.txt, CriptografiaPublica.txt,CriptografiaSecreta.txt, FirmaDigital.txt ), con las llaves pùblica, privada, secreta y la firma digital generada respectivamente.


/*******************************************************************************/
Llave Privada: Sun DSA Private Key
parameters:
p:
fca682ce 8e12caba 26efccf7 110e526d b078b05e decbcd1e b4a208f3 ae1617ae
01f35b91 a47e6df6 3413c5e1 2ed0899b cd132acd 50d99151 bdc43ee7 37592e17
q:
962eddcc 369cba8e bb260ee6 b6a126d9 346e38c5
g:
678471b2 7a9cf44e e91a49c5 147db1a9 aaf244f0 5a434d64 86931d2d 14271b9e
35030b71 fd73da17 9069b32e 2935630e 1c206235 4d0da20a 6c416e50 be794ca4

x: 05d1cd9b f2a50d95 ebd60b1f 92a6c366 b48c5246

Llave Publica: Sun DSA Public Key
Parameters:
p:
fca682ce 8e12caba 26efccf7 110e526d b078b05e decbcd1e b4a208f3 ae1617ae
01f35b91 a47e6df6 3413c5e1 2ed0899b cd132acd 50d99151 bdc43ee7 37592e17
q:
962eddcc 369cba8e bb260ee6 b6a126d9 346e38c5
g:
678471b2 7a9cf44e e91a49c5 147db1a9 aaf244f0 5a434d64 86931d2d 14271b9e
35030b71 fd73da17 9069b32e 2935630e 1c206235 4d0da20a 6c416e50 be794ca4

y:
d13969c4 4a72fc75 34c8a901 f9a7385c c5e0f58a f7e4ff2f 86c81303 34c88ead
174e69a5 2e419e0b 075af7f1 0b0ee3af 7e701dee 8e392760 afb42e5b 051bf3f3


Llave Secreta: com.sun.crypto.provider.DESKey@fffe78e4

DSA 'Llave Privada' 'DATOS ESPECIFICOS'
g: 5421644057436475141609648488325705128047428394380474376834667300766108262613900542681289080713724597310673074119355136085795982097390670890367185141189796
p: 13232376895198612407547930718267435757728527029623408872245156039757713029036368719146452186041204237350521785240337048752071462798273003935646236777459223
q: 857393771208094202104259627990318636601332086981
x (Private Key): 33223720685525160964687769090827582703053591110

DSA 'Llave Publica' 'DATOS ESPECIFICOS'
g: 5421644057436475141609648488325705128047428394380474376834667300766108262613900542681289080713724597310673074119355136085795982097390670890367185141189796
p: 13232376895198612407547930718267435757728527029623408872245156039757713029036368719146452186041204237350521785240337048752071462798273003935646236777459223
q: 857393771208094202104259627990318636601332086981
y (Public Key): 10957964172216934477577618607139934551345542158063249939755549047479274223759870433197949180499126827884422297601943888110924226391334218853590138250589171

Mensaje Transacciòn: Clave 'Privada' Guardada
Mensaje Transacciòn: Clave 'Publica' Guardada
Mensaje Transacciòn: Clave 'Secreta' Guardada

Mensaje Transacciòn: Clave 'Privada' Recuperada
Mensaje Transacciòn: Clave 'Publica' Recuperada
Mensaje Transacciòn: Clave 'Secreta' Recuperada

Mensaje Transacciòn: 'Firma Digital' Creada
Mensaje Transacciòn: 'Firma Digital' Guardada en Archivo
Firma Digital: 0, 5lE?Í"0Y"ššµ?
¬Dêãå± r“ ×)”f¡îM)ÕÃu†å1dXà
Existe Firma Digital: false
Mensaje Transacciòn: 'Firma Digital' Recuperada de Archivo
Obteniendo Firma Digital 'Archivo': 0, 5lE?Í"0Y"ššµ?
¬Dêãå± r“ ×)”f¡îM)ÕÃu†å1dXà

Listado Algoritmos 'KeyPairGenerator': [ECIES, GOST3410, ECGOST3410, EC, DIFFIEHELLMAN, ECDSA, DSA, ECDH, ECDHC, RSA, DH, ELGAMAL]
Listado Algoritmos 'Signature': [SHA256WITHRSAENCRYPTION, RSASSA-PSS, MD5WITHRSA/ISO9796-2, SHA256WITHECDSA, SHA384WITHECDSA, ECGOST3410, SHA256WITHRSA/PSS, DSA, ECDSA, MD4WITHRSAENCRYPTION, SHA384WITHRSA, RIPEMD128WITHRSAENCRYPTION, RIPEMD160WITHRSAENCRYPTION, SHA384WITHRSAENCRYPTION, SHA512WITHRSA, SHA224WITHECDSA, MD2WITHRSA, NONEWITHDSA, SHA256WITHECNR, SHA224WITHRSAENCRYPTION, SHA256WITHDSA, RIPEMD256WITHRSAENCRYPTION, SHA224WITHECNR, MD5WITHRSA, SHA1WITHRSAENCRYPTION, SHA256WITHRSA, SHA512WITHECDSA, SHA512WITHRSAENCRYPTION, SHA384WITHRSA/PSS, GOST3410, SHA1WITHRSA/PSS, SHA1WITHECNR, SHA1WITHDSA, SHA1WITHRSA/ISO9796-2, SHA512WITHRSA/PSS, SHA224WITHRSA/PSS, SHA224WITHDSA, SHA512WITHDSA, SHA1WITHRSA, MD5ANDSHA1WITHRSA, RIPEMD160WITHRSA/ISO9796-2, SHA512WITHECNR, SHA384WITHDSA, MD5WITHRSAENCRYPTION, MD2WITHRSAENCRYPTION, SHA384WITHECNR, 1.2.840.113549.1.1.10]

Lista Proveedores Encriptacion:
--------------------------------
SUN version 1.6
SunRsaSign version 1.5
SunJSSE version 1.6
SunJCE version 1.6
SunJGSS version 1.0
SunSASL version 1.5
XMLDSig version 1.0
SunPCSC version 1.6
SunMSCAPI version 1.6
BC version 1.36
/*******************************************************************************/


Para descargar el paquete completo: pulsar AQUI #1. - AQUI #2.

Sunday, March 29, 2009

Serializacion & Deserializaciòn de Objetos

En esta oportunidad muestro el manejo de 'Serializacion & Deserializacion de Objetos en Java'. Esto lo elabore en base de Objetos Stream, como sus dos mètodos famosos: 'writeObject' y 'readObject'. Los dos ejemplos que se muestran, realizan lo mismo impreso en consola, la diferencia que es que en el primer ejemplo el seteo de objetos esta en modo 'HardCode' y en el segundo utilizo un bean 'BeanSerializable' para la transmisiòn. En total los dos ejemplos cuantan con tres clases:

BeanSerializable.java

import java.io.Serializable;
import java.util.Date;

/**
* En clase es utilizada para el setedo de datos para su posterior serializacion.
*
* @version 1.2 - 29 Marzo 2009.
* @author Ricardo Guerra.
*/
public class BeanSerializable implements Serializable{

private static final long serialVersionUID = -7905579217165381885L;

private Integer codigo;
private String nombre;
private String apellido;
private Date fecha;


public static long getSerialVersionUID() {
return serialVersionUID;
}

public Integer getCodigo() {
return codigo;
}

public void setCodigo(Integer codigo) {
this.codigo = codigo;
}

public String getNombre() {
return nombre;
}

public void setNombre(String nombre) {
this.nombre = nombre;
}

public String getApellido() {
return apellido;
}

public void setApellido(String apellido) {
this.apellido = apellido;
}

public Date getFecha() {
return fecha;
}

public void setFecha(Date fecha) {
this.fecha = fecha;
}
}

Serializando_Deserealizando_Objetos_01.java

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;

/**
* En esta clase estoy mostrando el manejo de Serializacion y Deserealizaciòn
* de datos en modo 'HardCode'.
*
* @version 1.2 - 29 Marzo 2009.
* @author Ricardo Guerra.
*/

public class Serializando_Deserealizando_Objetos_01 implements Serializable{

private static final long serialVersionUID = -2071812553599487256L;


public static void main( String[] args ){

try{
/***************************************/
/**** ENVIAN OBJETOS 'Serializados' ****/
/***************************************/
FileOutputStream salida = new FileOutputStream( "objTemporal" ); //objTemporal, reconoce el nombre del Objeto de la Memoria.
ObjectOutput objSalida = new ObjectOutputStream(salida);

objSalida.writeObject( 123456 );
objSalida.writeObject( "Cesar Ricardo" );
objSalida.writeObject( "Guerra Arnaiz" );
objSalida.writeObject( new Date() );

objSalida.flush();
objSalida.close();


/********************************************/
/**** RECUPERAN OBJETOS 'Deserializados' ****/
/********************************************/
FileInputStream entrada = new FileInputStream( "objTemporal" ); //objTemporal, reconoce el nombre del Objeto de la Memoria.
ObjectInputStream objEntrada = new ObjectInputStream( entrada );

Integer codigo = (Integer)objEntrada.readObject();
String nombre = (String)objEntrada.readObject();
String apellido = (String)objEntrada.readObject();
Date fecha = (Date)objEntrada.readObject();

objEntrada.close();

System.out.println( "Objeto Deserealizado #01: " + codigo );
System.out.println( "Objeto Deserealizado #02: " + nombre );
System.out.println( "Objeto Deserealizado #02: " + apellido );
System.out.println( "Objeto Deserealizado #03: " + fecha );
}
catch( Exception e ){
e.printStackTrace();
}
}

public static long getSerialVersionUID() {
return serialVersionUID;
}
}

Serializando_Deserealizando_Objetos_02.java

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;

/**
* En esta clase estoy mostrando el manejo de Serializacion y Deserealizaciòn
* de datos utilizando un Objeto Bean de apoyo.
*
* @version 1.2 - 29 Marzo 2009.
* @author Ricardo Guerra.
*/

public class Serializando_Deserealizando_Objetos_02 implements Serializable{

private static final long serialVersionUID = -7282739136711013954L;


public static void main( String[] args ){

try{
BeanSerializable objeto = new BeanSerializable();

/***************************************/
/**** ENVIAN OBJETOS 'Serializados' ****/
/***************************************/
FileOutputStream salida = new FileOutputStream( "objTemporal" ); //objTemporal, reconoce el nombre del Objeto de la Memoria.
ObjectOutput objSalida = new ObjectOutputStream(salida);

objeto.setCodigo( 123456 );
objeto.setNombre( "Cesar Ricardo" );
objeto.setApellido( "Guerra Arnaiz" );
objeto.setFecha( new Date() );

objSalida.writeObject( objeto );

objSalida.flush();
objSalida.close();


/********************************************/
/**** RECUPERAN OBJETOS 'Deserializados' ****/
/********************************************/
FileInputStream entrada = new FileInputStream( "objTemporal" ); //objTemporal, reconoce el nombre del Objeto de la Memoria.
ObjectInputStream objEntrada = new ObjectInputStream( entrada );

BeanSerializable objetoBean = (BeanSerializable)objEntrada.readObject();

System.out.println( "Objeto: " + objetoBean );

if( objetoBean instanceof BeanSerializable ){
System.out.println( "Si es Instanciado al Objeto" );
}
else{
System.out.println( "No es Instanciado al Objeto" );
}

objEntrada.close();

System.out.println( "Objeto Deserealizado #1: " + objetoBean.getCodigo() );
System.out.println( "Objeto Deserealizado #2: " + objetoBean.getNombre() );
System.out.println( "Objeto Deserealizado #3: " + objetoBean.getApellido() );
System.out.println( "Objeto Deserealizado #4: " + objetoBean.getFecha() );
}
catch( Exception e ){
e.printStackTrace();
}
}

public static long getSerialVersionUID() {
return serialVersionUID;
}
}

Sunday, March 8, 2009

Administra tus Motores de Datos con DbVisualizer v6.5.1

Aqui les comparto una muy buena herramienta gràfica para la administraciòn de motores de base de datos llamada: 'DbVisualizer v6.5.1', es la mejor y mas completa herramienta que he encontrado hasta el momento, ya que permite desde una misma herramienta conectarse a todas las siguientes base de datos:

- db2
- derby
- h2
- hsqldb
- informix
- mysql
- oracle
- postgresql
- sqlserver
- sybase

y en simultaneo ya que de un mismo 'Arbol' se puede manejar varias conexiones para diferentes bases de datos. Ademas, lo mejor que las conexiones que usa la herramienta es en base JARs 'JDBC' (Todos los JARs estan adjuntos en el .ZIP).

Tambien, la herramienta te permite editar, modificar, eliminar datos de las tablas, importar y generar script SQL, etc. Incluso posee un visualizador gràfico de relaciones entre las tablas, partiendo de la tabla seleccionada.

Para visualizar como luce esta herramienta pulsar: Aquì

Para descargar esta muy buena herramienta pulsar Aquì

Para las librerías JDBC requeridas por la herramienta pulsar Aquì

Sunday, March 1, 2009

Manejo de Hilos (Threads) en Java

Aqui muestro el manejo de un Tema muy importante en JAVA. Hilos (Threads) que se utiliza para el manejo de varios proceso simultaneamente (Uno por cada Hilo creado).

En el demo preparado muestro dos formas de como manejar 'Threads', por medio de dos beans similares. El primero haciendo un 'extends Thread' y el segundo haciendo un 'implements Runnable'.

Espero que el demo sea ilustrativo y les de ideas para futuros manejos en otras aplicaciones.

Ademàs, para una informaciòn mas completa he colgado tambien un Tutorial en PDF donde muestras una informaciòn mas completa sobre este tema.

Para descargar la aplicaciòn Demo pulsar Aquì

Para descargar un buen tutorial en PDF pulsar Aquì

Friday, February 27, 2009

Manejo Objectos Generics

Aquì mostrarè un Ejemplo de como manejar Objetos (Setear y Acceder) de tipo Genrics.

Declaramos el Objeto 'BeanGenerico' y le ponemos que sea de tipo '< objetoGenerico extends Object >', que significa que en la variable 'objetoGenerico' se almacenarà cualquier tipo de valor que se le atribuya a la variable:

class BeanGenerico< objetoGenerico extends Object >{

private objetoGenerico codigo;
private objetoGenerico nombre;
private objetoGenerico apellido;
private objetoGenerico dni;
private objetoGenerico cumpleanos;

/*******************/
/**** GET - SET ****/
/*******************/
public objetoGenerico getCodigo() {
return codigo;
}
public objetoGenerico getNombre() {
return nombre;
}
public objetoGenerico getApellido() {
return apellido;
}
public objetoGenerico getDni() {
return dni;
}
public void setCodigo(objetoGenerico codigo) {
this.codigo = codigo;
}
public void setNombre(objetoGenerico nombre) {
this.nombre = nombre;
}
public void setApellido(objetoGenerico apellido) {
this.apellido = apellido;
}
public void setDni(objetoGenerico dni) {
this.dni = dni;
}
public objetoGenerico getCumpleanos() {
return cumpleanos;
}
public void setCumpleanos(objetoGenerico cumpleanos) {
this.cumpleanos = cumpleanos;
}
}


Luego creamos la Clase 'PruebaBeanGenerico', donde se Seteara y Accedera al Objeto anterior:

import java.math.BigDecimal;
import java.util.Date;

public class PruebaBeanGenerico{

static Integer anoPruebaInicio = 2009;
static Integer mesPruebaInicio = 12;
static Integer diaPruebaInicio = 3;

static Integer redondeoAñoFecha = 1900; //Redonde de Año.
static Integer redondeoMesFecha = 1; //Redonde de Mes.


@SuppressWarnings("deprecation")
public static void main( String[] params ){
BeanGenerico beanGenerico = new BeanGenerico();

BigDecimal codigo = new BigDecimal( 10 );
String nombre = new String( "Cesar Ricardo" );
String apellido = new String( "Guerra Arnaiz" );
Integer dni = new Integer(41816133);
Date cumpleanos = new Date( (anoPruebaInicio - redondeoAñoFecha), (mesPruebaInicio - redondeoMesFecha), diaPruebaInicio );

beanGenerico.setCodigo( codigo );
beanGenerico.setNombre( nombre );
beanGenerico.setApellido( apellido );
beanGenerico.setDni( dni );
beanGenerico.setCumpleanos( cumpleanos );

imprimir( beanGenerico );
}

public static void imprimir( Object parametro ){
BeanGenerico beanGenerico = (BeanGenerico)parametro;

System.err.println("");
System.err.println("OBTENIENDO DATOS 'GENERICs'");
System.err.println("Codigo: " + beanGenerico.getCodigo() );
System.err.println("Nombre: " + beanGenerico.getNombre() );
System.err.println("Apellido: " + beanGenerico.getApellido() );
System.err.println("Dni: " + beanGenerico.getDni() );
System.err.println("Cumpleaños: " + beanGenerico.getCumpleanos() );
System.err.println("");
}
}

De esta forma que resuelta la duda de como manejar los Objetos Generics en JAVA.

Manejo 'Enums'

Aqui les comparto un Ejemplo de como manejar la 'Enums' en JAVA. Para el manejo
de una lista de 'Constantes' en su interior y asi ya no estar declarando varias lineas Constantes.

Creamos la Clase 'ManejoEnum' y codificamos de esta maneja:


public class ManejoEnum{

public enum Paises{
PAIS_01( "PERU" ),
PAIS_02( "BRASIL" ),
PAIS_03( "ALEMANIA" ),
PAIS_04( "FRANCIA" );

private String mensaje;

Paises( String mensaje ){
this.mensaje = mensaje;
}

String getMensaje(){
return mensaje;
}

void setMensage( String mensaje ){
this.mensaje = mensaje;
}
}

public static void main( String[] args ){
System.out.println( "PAIS SELECCIONADO: " + Paises.PAIS_01.getMensaje() );
Paises.PAIS_01.setMensage("RUMANIA");
System.out.println( "PAIS SELECCIONADO: " + Paises.PAIS_01.getMensaje() );
}

}


El Ejemplo mostrara en 'Consola' lo siguiente:

PAIS SELECCIONADO: PERU
PAIS SELECCIONADO: RUMANIA

Tuesday, February 24, 2009

Cuando se malogra el 'Autocompletar' en Eclipse

A quién no le ha sucedido alguna vez que estado programando en Eclipse deja de autocompletar los códigos fuente en Java por arte de magia. Sin haber tocado nada y sin causa aparente. Arrancas el Eclipse tranquilamente y donde ayer completaba un .Java y pulsando "Ctrl + Barra Espaciadora" de la forma mas normal y hoy no. La solución es más simple de lo que se cree:

Desde Eclipse:

Window -> Preferences -> Java -> Editor -> Content Assist -> Advanced

Al llegar aquí lo más probable es que tengas desmarcadas todas las opciones y hacer un "Restore Defaults" y verás que se marcan varias opciones. Con esto el Problema del Autocompletar faltante esta solucionado.

Monday, February 23, 2009

Manejo Clases y Mètodos de JAVA.

Hola, en esta oportunidad presento una Clase que he desarrolado con la finalidad de dar a mostrar el manejo de distintan Clases de Java, que son y que no son muy cocidas y usadas, asi como el manejo sus mètodos correspondiente de estas, de una forma muy bien detallada. Las Clases, temas y mètodos de las que estoy mostrando su funcionamiento, son las siguientes:

- Recursividad
- StopWatch
- Validate
- Arreglos ( Dimensionales, Bidimensionales )
- ArrayListToArray
- ArrayUtils
- DateUtils
- StringUtils
- TimeZone
- SimpleDateFormat
- Calendar
- GregorianCalendar
- Date
- System
- HashTable
- Stack
- Enumeration
- Character
- Clases_Envoltorias
- bigInteger
- bigDesimal
- tipos_IF_ELSE
- comparativoCadenasSinConEspacios
- LinkedList
- ArrayList
- Vector
- HashMap
- Aleatorio #01
- Aleatorio #02
- StringBuffer
- Substring
- CompareTo

He subido un .Zip llamado 'Manejo_Clases_Metodos_Java.zip' que contiene en su interior un proyecto J2EE llamada 'Manejo_Clases_Metodos_Java', de Eclipse. Luego en el arbol de Eclipse se mostara la ruta: 'org.java.prueba' con las clases:


- PruebaClasesJava.java
- PruebaClasesJavaGUI.java
- Consola.java
- BeanComboBoxModel.java


La Clase que maneja todo esto la he llamado 'PruebaClasesJava.java' y para probar su funcionamiento se puede hacer de dos formas:

Forma #1:
Simplemente se descomenta el llamado al metodo de la Clase que se desea ver su funcionamiento y se ejecuta el Mètodo: 'public static void main( String[] args )'. El Resultado se mostrara en Consola.

Forma #2:
He colocado una Clase llamada 'PruebaClasesJavaGUI.java', que es en realidad una pequeña aplicacion realizada en 'Java SWING', donde al ejecutarce se puede escoger desde un ComboBox la Clase que se desea ver su funcionamiento, consultarlo y el
resultado se mostrara en un TextArea.

Para visualizar como luce la aplicaciòn pulsar:
Aquì.

Para descargar el paquete de la Clase junto con la aplicaciòn demo pulsar AQUI.

Thursday, January 15, 2009

TUTORIAL MAVEN

Este completo tutorial explica todo lo mas resaltante sobre Maven, en esta oportunidad la versión 2.0.9.

Esta muy buena herramienta nos puede ayudar en el proceso de creación de nuestro proyecto Java. ¿Cómo lo logra?, mediante el uso de los arquetipos de Maven, que son estructuras de proyecto predefinidas y reconocidas en un archivo xml (Pom.xml), que se generan mediante los plugins de Maven (Cada plugin de arquetipo relacionado a un Jars necesario). Además, los principales proyectos Open Source en Java, están utilizando cada día más el uso de Maven para su desarrollo, por lo que cada vez es más frecuente encontrar plugins de arquetipos para el desarrollo de aplicaciones.

Maven, para ser compilado necesita de requerimiento el Internet ya que mediante unos comandos en consola (Posteriormente explicaremos), Maven lee los plugins de arquetipos escritos en el archivo Pom.xml y descarga las librerías necesarias en un repositorio predefinido para el almacenamiento de las librerías respectivas.

También, Maven permite generar y versionar un Proyecto dentro de un War, ordenar y comprimir las librerías (Jars) utilizadas dentro de un .Zip, generar un completo JavaDoc de la aplicación, etc. Todo mediante códigos en consola.

El tutorial expuesto acontinuacion toca los temas:

I.- REQUISITOS.
II.- CARACTERISTICAS.
III.- INSTALACION DE MAVEN.
IV.- CREACION DE UN PROYECTO JAVA CON MAVEN.
V.- PROCESOS QUE SE PUEDEN HACER CON MAVEN.
VI.- MANEJO DEL POM.XML.
VII.- EXCLUSIONES EN LAS DEPENDENCIES.
VIII.- PROYECTO MULTIMÓDULO.
VIII.- CICLO DE VIDA.
IX.- INSTALACION DEL PLUGIN DE MAVEN PARA ECLIPSE.
X.- REPOSITORIOS IMPORTANTES DE MAVEN.
XI.- DEFINICIONES RÀPIDAS E IMPORTANTES DE MAVEN.
XII.- HERRAMINETAS REALCIONADAS CON MAVEN.
XIII.- ENLACES RELACIONADOS DE MAVEN.


Para descargar el Tutorial de Maven completo pulsar Aquì