lunes, 12 de noviembre de 2007

Visor LDAP: Ldap Browser

Para ver la estructura de un LDAP, una herramienta bastante útil y sencilla es el LDAP Browser:

1.-Tiene un .bat que tiene la siguiente información (el java debe estar en el classpath):


@echo off

set OPTIONS=

if "%1%" == "fix13" goto fix13
goto setjava

:fix13
set ARG1=
set OPTIONS=%OPTIONS% -Xbootclasspath/p:lib\ldap.jar;lib\jndi.jar;lib\providerutil.jar;lib\ldapbp.jar

:setjava
set ARG1=%1
if "X%JAVA_HOME%" == "X" goto nojavahome

set JAVA=
goto run

:nojavahome
set JAVA=java

:run
"java" %OPTIONS% -jar lbe.jar %ARG1% %2 %3 %4 %5 %6 %7 %8 %9


1.-Arrancar con el bat ( o el fichero correspondiente ).
2.-Luego, en File -> Connect -> Creamos una entrada
Host:127.0.0.1
Port: (El puerto en el que esté)
Base DN: ou=??,o=##,o=** (colocar las entradas correspondientes)
User DN: cn=Directory manager (usuario con permisos)
Password: la que se tenga
3.-Salvar
4.-File->Connect (se hace la conexión)
5.-Nótese, que estamos tirando contra un host:127.0.0.1, con lo cual, deberíamos tener o el servidor en local o tener abierto un túnel a la máquina en cuestión, o simplemente sustituir el Host por la dirección en la que esté el ldap (y tener acceso a ella claro).
6.-Una vez conectados, ya veremos el árbol determinado, podemos ver los usuarios, verificar contraseñas, ver atributos, crear usuarios,...

Analizando el tráfico web con tcpmon.jar

Problema: Queremos ver lo que estamos recibiendo como respuesta de un servicio web. Imaginemos que el servicio web está en http://dirServWeb:7777/masDir/masCarpeta
Solución:
1.-Con el tcpmon.jar, le damos doble click, introducimos en

localPort= 7777
ServerName= dirServWeb
ServerPort= 7777
...y le damos click en "Add Monitor"

2.-Luego la dirección donde teníamos http://dirServWeb:7777/masDir/masCarpeta pasa a ser http://localhost:7777/masDir/masCarpeta

3.-Posteriormente, entramos en la aplicación y ya podemos ver las respuestas.

Para más consulta: Web TCPMon

jueves, 27 de septiembre de 2007

Comparar dos ficheros en Windows

Muchas veces es importante comparar dos ficheros, para visualizar los cambios. Aún cuando existen instrucciones para hacerlo, normalmente no son potentes gráficamente hablando.

Para Windows uso esta herramienta gratuita, que a pesar de ser muy básico es muy intuitivo y descriptivo ExamDiff

miércoles, 26 de septiembre de 2007

JODE: Decompilador para Eclipse

Pasos para su instalación

1.-En el eclipse -> Help -> Find and install -> Search for new features
2.-Ahora en la nueva ventana, seleccionamos "New Remote Site", y luego, nos pedirá un nombre y una url, yo coloqué
Name: JODE
URL : http://www.technoetic.com/eclipse/update

3.-Ok, y luego Finish.
4.-Luego de la búsqueda, dará unos resultados, seleccionamos el que está bajo el nombre de "JODE" y Next
5.-Acepto los términos (leer :) )
6.-Next
7.-Finish
8.-Seguramente, dirá que el proveedor es desconocido, aquí, si aceptan la incertidumbre, pueden dar a "install" de todas formas
9.-Reiniciar el eclipse
10.-Ir a Window -> Preferences -> General -> Editors -> File Associations, selecciono el ".class" y debajo, en "Associated Editors" coloco al Jode Class File Viewer como "default".

Instrucciones oficiales del plugin

jueves, 6 de septiembre de 2007

mostrar lista de radio y de checkbox en una jsp siendo válida xhtml

Para checkbox usando una lista de PropertyBean metida en sesión. Obviar los estilos.
Notas: "IDIOMAS" podría estar en una clase SessionKey y luego llamarla con scriptles.
Sustituir "MENOR" por "<" y "MAYOR" por ">"
Quitar los espacios luego del "<"



< c:set var="jTab" value="347" scope="session"/> <%-- es el orden de tabulación del punto anterior--%>
< logic:iterate name="IDIOMAS" id="idioma">
< c:set var="jTab" value="${jTab+1}" scope="session"/>
< c:set var="identificadorIdioma" scope="session">
< div class="clearBoth">
< label for ="MENOR % =(String)request.getSession().getAttribute("identificadorIdioma") % MAYOR" >
< html:multibox property="myNotification.idiomasId" styleId='MENOR%=(String)request.getSession().getAttribute("identificadorIdioma") %MAYOR' tabindex='MENOR%=request.getSession().getAttribute("jTab") %MAYOR' >< bean:write name='idioma' property="value"/>
< bean:write name="idioma" property="label"/>
< /label>
< /div>
< /logic:iterate>




2.-Ejemplo para radio. Es el típico para escoger el sexo. Tendría un ActionForm llamado "miForm" con una propiedad "sexo". También se hace uso de un par de etiquetas del ApplicationResources para mostrar los textos.


< label for="sex.man">
< html:radio name="miForm" property="sexo" styleId="sex.man" value="hombre" >
< /html:radio>
< bean:message key="etiqueta.sexo.hombre" />
< /label>

< label for="sex.woman">
< html:radio name="miForm" property="sexo" styleId="sex.woman" value="mujer">
< /html:radio>
< bean:message key="etiqueta.sexo.mujer" />
< /label>

martes, 28 de agosto de 2007

Validación usando validation.xml, validator-rules.xml y un validador propio

Problema: Hacer un validador externo para ser usado desde el validation.xml.

Solución:
1.- Hago una clase que tenga mi método de validación

public class MiValidation implements Serializable{

/**
* Valida un dce con el formato de dos dígitos seguidos de una barra y luego 4 dígitos. Ej.: 33/12345
* @return false si no hubo error, true si hubo algún error
*/
public static boolean validateDCE(java.lang.Object bean,
org.apache.commons.validator.ValidatorAction va,
org.apache.commons.validator.Field field, ActionMessages errors,
Validator validator, javax.servlet.http.HttpServletRequest request) {
// reflejamos el metodo en el logger
if (ValidationCortas.logger.isDebugEnabled()) {
ValidationCortas.logger
.debug("ValidationCortas: Método validateDCE");
}

// miramos si el objeto es un string
String value = null;
if (MiValidation.isString(bean)) {
// metemos el string en la variable value
value = ((String) bean);
} else {
// obetenemos el valor del bean
value = ValidatorUtils.getValueAsString(bean, field.getProperty());
}

// comprobamos que tenga algo
if (!GenericValidator.isBlankOrNull(value)) { //esa función es propia es para que no sea null o cadena vacía
String expReg = "^(\\d{2})(/\\d{4})$"; //ej.: 33/12345
boolean mach=value.matches(expReg);
if (value.matches(expReg) ){
return (false);
}else{
errors.add(field.getKey(), Resources.getActionMessage(request, va,
field));
return (true);

}
}
return (false);
}

/**
* Método que determina si el objeto es o no de tipo String
*
* @param Object o, el objeto a analizar
* @return boolean true si es String, false en caso contrario o si es null
*/
private static boolean isString(Object o) {
// si es null, es string
if (o == null) {
return (true);
}
return (String.class.isInstance(o));
}

} //fin de la clase


2.-En el validator-rules hago un validador. El msg lo extraerá del ApplicationResources respectivo. Nota: Quitar los espacios luego del '<'

< validator name="validateDCE"
classname="es.mipaquete.web.validator.MiValidation"
method="validateDCE"
methodParams="java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest"
depends=""
msg="errors.invalid.dce" >
< /validator>


3.-En el validation.xml, indico que campo del formulario está sometido a la validación. En el ejemplo muestro como colocar para el form. El key que coloco lo
extraerá del ApplicationResources respectivo. Nota: Quitar los espacios luego del '<'


< formset>
< form name="miFormBase">
< field property="maderistaForm.calificacionEmpresarial" depends="validateDCE">
< arg0 key="error.maderista.calificacionEmpresarial" name="validateDCE"/>
< /field>
< /form>
< /formset>


4.-En el ApplicationResources meto las variables necesarias:

errors.invalid.dce=\"{0}\" debe ser un DCE válido, ejemplo: 33/9999.
error.maderista.calificacionEmpresarial = Documento de Calificación Empresarial


5.-Queda colocar en struts que el validate=true y el input en el action correspondiente.

miércoles, 22 de agosto de 2007

Ordenando una lista Collections

Para ordenar una lista en Java, basta con implementar un comparador y hacer una llamada a la clase Collections. Incluso puede hacerse con una clase anónima como es el ejemplo que les muestro:


LinkedList solicitudes = new LinkedList();
/*imaginemos que miDelegate.getSolicitudes() me devuelve una lista LinkedList donde cada elemento es un objeto de tipo MiObjeto, que lo que tiene es un atributo long llamado id*/
solicitudes = miDelegate.getSolicitudes();

Collections.sort(solicitudes,
new Comparator()
{
/**
* Metodo encargado de realizar la comparacion.
* Ordena descendentemente por el identificador.
*/
public int compare(Object a, Object b)
{
long idA = Long.parseLong(((MiObjeto)a).getId());
long idB = Long.parseLong(((MiObjeto)b).getId());

if (idA>idB){
return -1;
}else if (idA<idB){
return 1;
}else{//son iguales
return 0;
}
}
}
);

lunes, 16 de julio de 2007

Imprimiendo mensajes de error para relacionar con html:errors

Problema: Queremos imprimir mensajes de error para que sean tomados por la etiqueta

Soluciones: Dependiendo de la versión de struts que usemos valdrán unas u otras.

Solución con ActionMessages: Hago un método que redirigirá y con el código del almacenamiento del mensaje dentro. Puede variar el método, pero el registro del error es casi idéntico siempre.

protected ActionForward findSuccess(ActionMapping mapping, ActionForm arg1, HttpServletRequest request, HttpServletResponse arg3) {


if (this.getActionParameter(ExceptionCortasKeys.PARAM_ID_NO_SELECCIONADO)!=null){
String mensaje = new String("Mensaje de error a mostrar");
// registramos el error
ActionMessages errores = getErrors(request, true);
errores.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("idErrorGlobal", mensaje));
saveErrors(request, errores);
//redirijo a la página de input del mapeo de struts
return mapping.getInputForward();
}

return super.findSuccess(mapping, arg1, request, arg3);
}


Solución con ActionErrors:
Explicación idéntica que lo anterior, varía el tipo de mensajes, es decir, el registro del error, quedando así:

ActionErrors errors = getErrors(request, true);
errors.add(ActionErrors.GLOBAL_ERROR,
new ActionError("global.princastexception", exception.getMessage()));
saveErrors(request, errors);

Mostrando pdf usando struts.

Problema: Queremos poner un enlace para que se llame un action y se muestre un pdf (típica ventana para abrir o descargar). El pdf nos viene en un array de bytes.

Solución: Desde la propia action que es llamada desde el enlace, colocaríamos el siguiente código:



try{
//obtengo el array de bytes del pdf
byte[] respuestaByte= this.miDelegate.getPDF();

//digo que es un pdf
response.setContentType("application/pdf");

//asigno el nombre del pdf, para cuando el usuario lo abra o descargue
response.setHeader("Content-Disposition",("attachment;filename=\"" +
nombrePDF+ ".pdf\""));

int longitud = respuestaByte.length;

//especifico el tamaño
response.setContentLength(longitud);

/*volcando a fichero*/
ServletOutputStream ouputStream = response.getOutputStream();

ouputStream.write(respuestaByte);

ouputStream.flush();

ouputStream.close();

}
catch(Exception e){
logger.error("No se ha podido regenerar correctamente el pdf");
}

miércoles, 4 de julio de 2007

Órdenes varias para oc4j

Imaginemos un contenedor llamado OC4J_MICONT
.-Comprobar el estado de la instancia OC4J_MICONT:
opmnctl status

.-Levantar la instancia OC4J_MICONT
dcmctl start -co OC4J_MICONT
opmnctl startproc process-type=OC4J_MICONT
opmnctl stopproc process-type=OC4J_MICONT

OJOOOOOOOOO.....ES MEJOR USAR LO SIGUIENTE:
opmnctl stopproc process-type=OC4J_MICONT
opmnctl startproc process-type=OC4J_MICONT

.-Reiniciar la instancia
dcmctl restart -co OC4J_MICONT

.-DEPLOY
dcmctl deployapplication -f nombreEar.ear -a miAplicacion -co OC4J_MICONT

.-UNDEPLOY
dcmctl undeployapplication -a miAplicacion -co OC4J_MICONT
Nota: A veces puede no funcionar bien el undeploy, con lo cual, puede que al listar las aplicaciones no aparezca, pero en realidad, si vamos al directorio del contenedor y vemos dentro del directorio applications o del applications-deployments puede estar; en ese caso, borrar los ears y carpetas relacionados.

.-LISTA DE APPLICATIONS
dcmctl listapplications -co OC4J_MICONT

jueves, 10 de mayo de 2007

Pasando expresiones regulares. JMeter


Muchas veces, necesitamos que la respuesta de una petición http, sea un parámetro de otra(s) peticiones posteriores. Ello se realiza de la siguiente manera:

1.-Para una petición http, añadimos un post-procesador "Extractor de Expresiones Regulares".
**Nombre: El que trae por defecto o algo descriptivo.
**Nombre de referencia: De esa forma llamaremos a la variable posteriormente.
**La expresión regular:
**Plantilla: De las partes del resultado de la aplicación de la expresión regular, podemos querer tomar la primera ($1$), la 2da ($2$), ...
**Coincidencia: lo dejo en blanco
**Valor por defecto: Si realmente nos interesa poner uno por defecto, se escribe aquí.

2.-Posteriormente, en otra petición http posterior, pondremos, por ejemplo, en los parámetros, al nombre del parámetro y el valor será ${nombre_de_referencia}.

Ejemplo: Quiero tomar de la respuesta de una petición todo un fichero xml que me viene como respuesta, y que empieza como "XML". La variable será varXML y aplico la expresión regular correspondiente.

Nombre de referencia: varXML
Expresión regular: name="XML" value="(.+?)"
Plantila: $1$

....luego en otras peticiones, en uno de sus parámetros tengo:
Nombre: miXML
Valor: ${varXML}

Importante: La respuesta suele venir en plano, es decir, sin codificar, por lo cual, es posible que para que funcione bien, el parámetro le tengamos que señalar que lo queremos codificado!!!!.


Para mayor referencia:
1.-http://wiki.apache.org/jakarta-jmeter/RegularExpressions
2.-http://wiki.apache.org/jakarta-jmeter/JMeterFAQ#head-87f846dad28fd6b2ad5eb0d44d527d572f810653
3.-Para probar expresiones regulares

JMeter. Creando una prueba


1.- Crear un Plan de pruebas:
1.1.- Ponerle un nombre

2.- Crear un grupo de hilos, para el plan de pruebas (añadir -> grupo de hilos):
2.1.- Nombre.
2.2.- Yo le coloqué 1 hilo.
2.3.- Período de subida le escribí un segundo.
2.4.- Bucles o ejecuciones: se le colocan cuantas se quieran, por ejemplo, 8. Esto quiere decir que intententará llegar hasta el final ese número de veces, si llega antes pues seguirá con otra prueba.

3.- Crear un controlador simple, para el grupo de hilos (añadir -> controlador lógico ->controlador simple):
3.1.- Gestor de cabecera http: Se suele colocar una cabecera como la siguiente.
Host: del que hacemos uso.
Accept-Language: es
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)
Pragma: no-cache
Content-type: application/x-www-form-urlencoded
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*

3.2.- Gestor de cookies http: Selecciono Cookie policy = compatibility.
3.3.- Modificador de parámetros de usuario: Lo que trae por defecto. Lo que dice es tomar el users.xml para los datos de usuario. El users.xml es un fichero que estará en el directorio bin del jmeter. Los parámetros que espera de los usuarios se los podemos poner allí, ejemplo de datos:
requester.nif05332135E
requester.nif95400774V

3.4.-Petición http: Ahora tendré que simular todos los pasos que quiero realizar, llamadas a páginas, paso de parámetos,...
Importante: Mucho de lo que aquí se configura es común para todos los pasos, entonces, eso común lo colocamos en el Gestor de Cabecera HTTP, y lo dejamos vacío aquí.
.-Nombre: Para identificar este paso
.-Nombre de Servidor o IP:
.-Puerto:
.-Protocolo: Ej.: http.
.-Método: Pues el que se haya elegido de GET, POST,...
.-Path: Ruta, empieza por /, y es lo que se concatenará al protocolo://nombre de servidor o ip.
.-Utilizar KeepAlive
.-Enviar Parámetros con la Petición:
**Nombre del Parámetro.
**Valor del Parámetro.
**Codificar: Significa si quieres que lo codifique al enviarse, en base 64
**Incluir Equals?: Si había signos "=" los deja.

4.- Añado varios listener al grupo de hilos:
4.1.- Informe Agregado: Representa un informe global de las pruebas, con los % de errores, pasos, datos estadísticos,...
4.2.- Ver árbol de resultados: Puedes observar las peticiones y respuestas http, ver las salidas html o xml si las hubo.
4.3.- Ver resultados en árbol: Ves si van teniendo éxito las pruebas y en qué tiempo.

martes, 17 de abril de 2007

Ingeniería Inversa con Enterprise Architect con java

1.-Creamos un nuevo proyecto
2.-Menú 'Project' -> 'Source Code Engineering' -> 'Import Source Directory'
Se nos abrirá una ventana, donde colocaremos lo siguiente:
.-Root Directory: ..../src/java/mi_dir_base_fuente
.-Source Type: java
.-File Extensions: java

.-Marcamos:
'Recursively Process Subdirectories' para que examine recursivamente
'Create Logical Diagram for Each Package' para que para cada uno de los paquetes que tengamos cree su estructura lógica (facilita la visualización)

.-Package Structure:
Yo selecciono la opción 'Create Package per Namespace', (lo uso para que cree un paquete por cada espacio de nombres que haya)
.-Synchronization
Synchronize existing classes

lunes, 16 de abril de 2007

Accediendo remotamente a tu equipo Windows

Muy bueno, incluso te dice si tienes ip dinámica como 'simularla' fija mediante no-ip.

Configurando acceso remoto

viernes, 13 de abril de 2007

Tablas de codificaciones de caracteres

Una página útil para las conversiones base64, html, uri,... HTML Encoder

jueves, 12 de abril de 2007

Red de contactos profesionales

Hace poco me pasaron un enlace a una página que me pareció, al menos, curiosa.
Es una página en la cual tienes como una 'agenda de contactos', que se usa más que nada para el entorno profesional, y que te dispone de tener una dirección con tu cv accesible.
Si quieres contactar con una persona de la red, te diría a cuántos 'grados' estás de él, es decir, cuántas personas les separan y a través de quién puedes contactarle.

La página en cuestión es eConozco

jueves, 22 de marzo de 2007

Imprimir excepciones en código de jsp

Problema: Cuando una jsp nos está generando un error, y queremos saber cuál es, pero no mostrárselo al usuario.

Solución: (Quitar los espacios después de los '<')

Agregar en una tile, el pie siguiente...o colocar el código correspondiente en cada jsp que queramos lo planteado.


< %@ page isErrorPage="true" %>
< %@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %>
< %@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html" %>

< !--
Información de errores JSP

< % if (exception != null) { %>
< pre><% exception.printStackTrace(new java.io.PrintWriter(out)); %>< /pre>
< % } else { %>
No hay ninguna excepcion visible, chequea los logs en busca del error
< % } %>
-->

miércoles, 21 de marzo de 2007

Confirmación de cancelar usando js

Problema:
Quiero que al pulsar un botón que en mi aplicación sirve para cancelar, me salga un popup para confirmar que lo deseo hacer.

Solución:
1.-Agrego una función javascript

/**
* Función para confirmar la cancelación de trámite
*/
function confirmCancel()
{
var message = "Ha seleccionado cancelar el proceso de solicitud que esta realizando.\n"
+ "?Desea cancelar realmente el proceso de solicitud?";
if (window.confirm(message))
{
document.forms[0].submit();
}
else
{
return (false);
}
}


2.-Hago la llamada de la función en mi botón (en mi caso es un html:submit, pero podría hacerse en el input de tipo submit normal y corriente), en el onclick: (quitar los espacios luego del <)



< html:submit property="buttons[14]"
altKey="boton.cancelar"
titleKey="boton.cancelar"
onclick="return confirmCancel();">

< /html:submit>

Poner dd/mm/aaaa en un text con javascript

Problema: Quiero colocar en un input para poner la fecha de nacimiento lo siguiente: dd/mm/aaaa, y que cuando el usuario escriba, este texto desaparezca.

Solución:
1.-En un fichero de funciones js coloco las siguientes:

//funcion para borrar el valor del campo de fecha
function clearFecha(){
if(document.getElementById("dateOfBirth").value=="dd/mm/aaaa"){
document.getElementById("dateOfBirth").value = "";
document.getElementById("dateOfBirth").style.color = "#000";
}
}

//funcion para cargar el valor del campo fecha como "dd/mm/aaaa", se coloca directamente en el texto con el identificador 'fechaNacimiento'
function loadFecha(){
if((document.getElementById("fechaNacimiento").value=="")||(document.getElementById("fechaNacimiento").value==null)||(document.getElementById("fechaNacimiento").value=="dd/mm/aaaa")){
document.getElementById("fechaNacimiento").value = "dd/mm/aaaa";
document.getElementById("fechaNacimiento").style.color = "#CCC";
}
}


2.-Hago las llamadas desde la página: (Quitar los espacios luego de '<')

< html:text name="miForm" onfocus="clearFecha();" styleId="fechaNacimiento" property="fechaNacimiento" size="10" maxlength="10" readonly="false"/>
< span onclick="clearFecha();">


3.-Recordar hacer el include en la jsp, algo como: (Quitar los espacios luego de '<')

< script src="scripts/empleo.js" type="text/javascript">< /script>

martes, 20 de marzo de 2007

Puedes colaborar :)

Bueno, viendo unas cosas que estaba haciendo un compañero de trabajo llegué -clicando y clicando y clicando, artículo va, noticia viene...-, a la siguiente página:

HacesFalta.org, es una web en la que puedes ser voluntario, buscar algún trabajo remunerado siempre relacionado con ong's o afines...hay ofertas para hacerlo desde tu casita: voluntario virtual.

Ahí lo dejo, por si le entra la vena colaborativa, o tienen ganas y un tiempito libre.

lunes, 19 de marzo de 2007

Displaytag: Ordenando columna por fecha

Si tenemos una tabla de la displaytag, en la que quiero que una columna ordene por fecha es algo más complicado que lo que se suele hacer, ya que, normalmente ordena alfanuméricamente.

Solución (Ordena por dd/MM/yyyy):

1.-Agrego la fecha, e indico el decorador que usa.

< display:table name="sessionScope.miLista"
align="center"
id="elemento"
pagesize="10"
export="false"
requestURI="../../action/citizen/MiAction?method=miMetodo">


< display:column titleKey="fechaConvocatoria"
property="fecha"
sortable="true"
decorator="es.miproyecto.web.view.DateColumnDecorator"/>
< /display:table>



2.-Agrego la clase java correspondiente al decorador.

package es.princast.personalSelection.web.view;

import java.text.SimpleDateFormat;
import java.util.Date;
import org.displaytag.decorator.ColumnDecorator;
import es.princast.personalSelection.util.DateDecorator;

/**
* Decorador para formatear la fecha en la tabla de listado
*
*/
public class DateColumnDecorator implements ColumnDecorator
{

/**
* Formateador de la fecha
*/
private SimpleDateFormat dateFormat = new SimpleDateFormat( "dd/MM/yyyy" );

/**
* Transformamos la reprentacion actual de la fecha en un string
*
* @param columnValue Object, el objeto date
*
* @return String value, el objeto string
*/
public final String decorate(Object columnValue)
{
if (columnValue!=null){
Date date = (Date) columnValue;
return this.dateFormat.format(date);
}else{
return new String("");
}
}
}

jueves, 15 de marzo de 2007

XSLT y eclipse

Hace tiempo en un curso (transparencias del curso) me mostraron un plugin bueno para eclipse el de orangevolt. Te permite hacer búsquedas con XPath, trae un editor XML, ejecutar las transformaciones...

Las páginas son las siguientes:
Página de orangevolt para eclipse
Página del plugin eclipsexslt de sourceforge (para descargas)

Es muy fácil de descargar, según la versión de eclipse que tengas, te descargas un versión u otra, la descomprimes, y colocas en features los archivos que te trae, y análogamente con plugins.

miércoles, 14 de marzo de 2007

XML y XSL con oc4j10

Bien, para hacer un xml con su xsl en oc4j (10 en mi caso), seguí las instrucciones de la página oficial...
instrucciones oficial

...sin embargo, resumo lo que entienden ahí como que 'todo el mundo lo sabe' y sino manuales y manuales.

1.-Agrega los jars que te indica en la página oficial en tu classpath:
a.-ojsputil.jar (está en oc4j\j2ee\home\jsp\lib\taglib)
b.-xmlparserv2.jar (está en oc4j\lib)
c.-xsu12.jar (está en oc4j\lib)

2.-En tu oc4j tienes los ejemplos que te ponen en la página, en la dirección:
oc4j\j2ee\home\demo\jsp\build\web\ojspdemos-web\jsp\xml . Así que con copiar y pegar en tu aplicación vale.

3.-La taglib uri de hello.xml cámbiala y coloca la siguiente:

<% @ taglib uri="/WEB-INF/tld/xml.tld" prefix="xml" %>

3.-En el web.xml de tu aplicación coloca, en la zona de los taglibs:

< taglib>
< taglib-uri>/WEB-INF/tld/xml.tld
< taglib-location>/WEB-INF/tld/xml.tld
< /taglib>

4.-Del jar ojsputil.jar que antes agregaste, extrae la xml.tld que está dentro de META-INF. Agrega esa tld en tu proyecto, en la ruta (location) indicada en el web.xml, que en este caso es /WEB-INF/tld/xml.tld .

5.-Arranca la jsp de hello.jsp y ¡LISTO!.

martes, 13 de marzo de 2007

Visor de logs: Chainsaw

Usando log4j para la generación de logs ya ha sido un primer paso.
Problema:Ahora está el engorro cuando el fichero es muy grande y el tiempo en pasarse al fichero.
Solución: Para verlo "en caliente" uso el Chainsaw . Es muy útil además, porque me permite buscar, filtrar por nivel de log,...

Lo que hago es colocar en el log4j.xml lo siguiente:
Nota: Quitar los espacios luego de los '<'.

< appender name="SOCKET" class="org.apache.log4j.net.SocketAppender">
< param name="Port" value="4445"/>
< param name="RemoteHost" value="localhost"/>
< param name="ReconnectionDelay" value="60000"/>
< param name="Threshold" value="DEBUG"/>
< /appender>


...y también lo agrego en el root para que me muestre desde la raíz.


< root>
< priority value="INFO"/>
< appender-ref ref="SOCKET"/>
< appender-ref ref="HTML"/>
< /root>


Finalmente, arranco el chainsaw, normalmente antes que mi servidor de aplicaciones, y ya me mostrará los logs por su consola.

lunes, 12 de marzo de 2007

'SetParameter' para la request

Me he topado con la necesidad de pasar por request un parameter, pero sólo tengo lo de "setAttribute" desde un Action.

Solución:
1.-Yo uso DispatchAction, pues en algún método que retorne ActionForward y que sea el que usen de base (en mi caso findSuccess), hacen lo siguiente:
  
//obtengo el path actual de la request
String uri = ServletPathUtils.getCompleteURL( request );
//llamo a la función que me da la nueva url a la que quiero ir
String url=miRequestNueva(uri);
//retorno el action forward con el redirect a true para que me redirija.
return ( new ActionForward( url,true ) );


2.-Función que me da la nueva dir a la que quiero ir

private String miRequestNueva(String uri){
String miRequestPath=uri;
//tomo la url y lo que hay luego de la última barra lo voy a cambiar
int ultimoIndexBarra= miRequestPath.lastIndexOf("/");
String primeraParte=miRequestPath.substring(0,ultimoIndexBarra+1);
//esto va a ser el final de mi request, cambio el action y paso un parámetro
String segundaParte="NuevaAction?paginate=true;
String requestCompuesta=primeraParte+segundaParte;
return requestCompuesta;
}

miércoles, 7 de marzo de 2007

Repopulando html:checkbox

Imaginemos que tengo 2 pantallas, la 1ra. de un formulario, y la siguiente, donde se presentan los datos introducidos en la primera.
En la 2da. tengo un check que puedo marcar o desmarcar, y lo que quiero es, que si vuelvo a la 1ra. se me quede almacenado lo que tengo en el check.
Puede haber otra solución, como recomiendan en la documentación del taglib, que sea poner en el reset el valor a false, pero esto no funciona si tengo varios botones en la página que redirigen a sitios distintos.

Solución:
1.- En el Form asociado tengo un atributo de tipo boolean, que en este caso llamo clausulas, con su respectivos getter y setter. Por defecto, quiero que aparezca marcado, con lo cual, coloco = true en su declaración.
2.- En la página de los datos, pongo el checkbox.
3.- Coloco también un atributo oculto con el mismo nombre que la propiedad y el valor de false. Si se desmarca el checkbox se envía el false, y si está marcado, se envía el true del checkbox.





lunes, 26 de febrero de 2007

Certificado Digital

Me saqué hace un tiempo ya un certificado digital por la casa de monedas, es realmente rápido y sirve para gestiones como sacar tu vida laboral por internet, te permite presentar declaraciones a hacienda (no lo he hecho y requiere más aprobaciones),...

http://www.fomento.es/MFOM/LANG_CASTELLANO/OFICINA_VIRTUAL/FIRMA_ELECTRONICA/gestionar_certificado.htm

jueves, 22 de febrero de 2007

Crear y eliminar contenedores en oracle

Para crear un contenedor que sea un oc4j:
dcmctl createcomponent -co NOMBRE_CONTENEDOR_A_CREAR -ct oc4j

Para borrar un contenedor:
dcmctl removecomponent -co NOMBRE_CONTENEDOR_A_BORRAR

Altura mínima y dinámica de divs de css usando js

Muchas veces tenemos, por ejemplo, un menú lateral con un determinado fondo y queremos que cuando el contenido central vaya creciendo pues el color del menú se extienda hasta abajo.

Esto se logra con un js que me encontré, para llamarlo basta citarlo con la ruta correspondiente (quitar los espacios después del '<'):

< script language="JavaScript" src="./column.js">< /script>


...ahora sí: la función js:


// by Paul@YellowPencil.com and Scott@YellowPencil.com
// feel free to delete all comments except for the above credit

function setTall() {
if (document.getElementById) {
// the divs array contains references to each column's div element.
// Replace 'center' 'right' and 'left' with your own.
// Or remove the last one entirely if you've got 2 columns. Or add another if you've got 4!
var divs = new Array(document.getElementById('contenido'), document.getElementById('enlaces'), document.getElementById('menu'));

// Let's determine the maximum height out of all columns specified
var maxHeight = 0;
for (var i = 0; i < divs.length; i++) {
if (divs[i].offsetHeight > maxHeight) maxHeight = divs[i].offsetHeight;

}

// Let's set all columns to that maximum height
for (var i = 0; i < divs.length; i++) {
divs[i].style.height = maxHeight + 'px';

// Now, if the browser's in standards-compliant mode, the height property
// sets the height excluding padding, so we figure the padding out by subtracting the
// old maxHeight from the new offsetHeight, and compensate! So it works in Safari AND in IE 5.x
if (divs[i].offsetHeight > maxHeight) {
divs[i].style.height = (maxHeight - (divs[i].offsetHeight - maxHeight)) + 'px';
}
}
}
}

window.onload = function() {
setTall();
}

window.onresize = function() {
setTall();
}

miércoles, 21 de febrero de 2007

Firefox bloquea el ir a una página por culpa de su puerto

Cuando estamos navegando con firefox y sale un mensaje como "Esta dirección usa un puerto de red que normalmente se utiliza con fines distintos a la navegación web. Para su protección, Firefox ha cancelado la petición."; entonces debemos editar un fichero de preferencias:

(os lo muestro en Windows)
1.-
C:\Archivos de programa\Mozilla Firefox\greprefs
Editar el fichero all.js y colocar pref("network.security.ports.banned.override", "nro_puerto"); donde está puesto nro_puerto pues sustituímos por el número en cuestión (ej.: 102)

2.-Reiniciar Firefox

martes, 20 de febrero de 2007

Mis extensiones firefox

Mis imprescindibles:

WebDeveloper: Para el desarrollo web, la imprescindible. https://addons.mozilla.org/firefox/60/
ScreenGrab: Permite capturas completas de la página como imagen. http://screengrab-extension.softonic.com/ie/43517
FireShot: Permite capturas completas de la página y editarlas colocándole notas. Sólo para Windows. https://addons.mozilla.org/en-US/firefox/addon/5648
Form Saver: Permite salvar formularios para no tener que rellenar siempre páginas. https://addons.mozilla.org/en-US/firefox/addon/1490
MeasureIt!: Es una regla (la webdeveloper tiene una similar). https://addons.mozilla.org/firefox/539/
del.icio.us: Son "mis favoritos" o "mis marcadores" disponibles desde cualquier parte, y esta extensión me permite añadir con mayor facilidad. http://del.icio.us/help/firefox/extension. Para más información ir a la página de del.icio.us.
DummyLipsum: Utilísima para crear los típicos textos de "lorem ipsum...". https://addons.mozilla.org/firefox/2064/
TAW3: Extensión del taw (accesibilidad) http://www.tawdis.net/taw3/cms/es/herramientas/extension.html
Document Map Extensión para ver la estructura de encabezados. https://addons.mozilla.org/es-ES/firefox/addon/475
TamperData: Para ver las peticiones http. https://addons.mozilla.org/firefox/966/
IETab: En una nueva pestaña ves el aspecto en el explorer (no disponible para linux). https://addons.mozilla.org/firefox/1419/
Firebug Estilo webdeveloper, pero tiene muy buenas opciones para ediciones y monitorizaciones de dom y css. https://addons.mozilla.org/es-ES/firefox/addon/1843
ViewSourceChart: El código fuente con colores por bloques. https://addons.mozilla.org/firefox/655/
ShowCase: Muestra una ventana con thumbnails de las pestañas abiertas, permitiéndote seleccionar cualquiera. Permite la rápida ubicación de una pestaña. https://addons.mozilla.org/en-US/firefox/addon/1810
JavaScriptDebugger: Para depurar javascript, aunque no me gusta mucho, tiene una consola útil de los mensajes de error. https://addons.mozilla.org/firefox/216/
Professor X: Puedes ver código javascript y css de la página. https://addons.mozilla.org/firefox/2823/
Visor JS: Permite ver el código JS externo. https://addons.mozilla.org/firefox/2076/

Enlaces relacionados:
1.-Extensiones Firefox
2.-Blog de extensiones
3.-Artículos sobre firefox

viernes, 16 de febrero de 2007

Así es la vida del desarrollo software....

En un desarrollo software hay muchos puntos de vistas, tantos como agentes involucrados y ya no sólo por la función que desempeñan sino por la propia persona, pero se resume muy bien en la siguiente imagen. Aunque, por otra parte, yo agregaría fondos tormentosos cuando se acerca el fin del proyecto ;).

Abator: generando ibatis automáticamente

Para los que usan ibatis, que es un mecanismo para sentencias sql y mapeos entre VO's que yo uso en Java, aquí tienen la forma de generar automáticamente algunos ficheros de configuración.
En pocas palabras, genera los VO's y los ficheros XML a partir de la base de datos.

http://ibatis.apache.org/abator.html
http://ibatis.apache.org/docs/tools/abator/

Vertical-align

Artículo en inglés, aunque tiene varias traducciones, sobre cómo centrar verticalmente para varios navegadores y css

http://www.jakpsatweb.cz/css/css-vertical-center-solution.html

Instalar ie7 en linux

http://www.bootlog.cl/blog/internet/ie7-para-linux-mas-facil-que-en-windows/

¿Cuándo poner un botón y cuándo poner un enlace?

Nos recuerda algunas pautas para decidir si poner un botón o un enlace:

http://www.alzado.org/articulo.php?id_art=633

CSS distintas para los navegadores

Bien sabido es que cada navegador interpreta las css casi que a su modo y ello obliga a hacer pequeñas modificaciones para uno u otro navegador.

Para hacer que nuestras páginas tomen una css u otra yo realizo lo siguiente:
(Nota: quitar los espacios después de '<')

1.-La css que me sirve de base la hago basada en firefox y luego genero otras para hacer las modificaciones.


< link type="text/css" rel="stylesheet" href="../css/css_base.css" />


2.- Para la css que modifica para explorer 7


< !--[if gte IE 6]>
< link rel="stylesheet" type="text/css" media="screen" href="../css/ie7_bug.css" />
< ![endif]-->


3.- La css que modifica para explorer 6


< !--[if IE 6]>
< link rel="stylesheet" type="text/css" media="screen" href="../css/ie6_bug.css" />
< ![endif]-->


A destacar:
Los atributos puesto con '_' (que sólo los veía explorer 6 o anteriores) no son válidos por el w3c.
Los estilos que coloquemos con *> el explorer 7 sí los interpreta (aunque no del todo bien) y el explorer 6 no. El firefox también los interpreta.

Abrir automáticamente una impresión de una página html

Muchas veces al abrir una ventana queremos que se lance la ventana de impresión automáticamente, esto se consigue con un iframe oculto (accesibilidad=0).

1.-Función js para detectar el tipo de navegador, porque la impresión se lanzará de manera diferente (hace uso de la función para detectar el navegador que tengo en otro post):

/*Función que imprime el frame oculto*/
function imprimoFrame(){
var tipo = tipoNavegador();
if (tipo==1){
window.frames["popUpImpresion"].focus();
window.frames["popUpImpresion"].print();
}else{
if (tipo==2){
document.popUpImpresion.focus();
document.popUpImpresion.print();
}else{
if (tipo==3){
document.popUpImpresion.focus();
document.popUpImpresion.print();

}
}
}
}

2.-Coloco en mi página el iframe: (quitar el espacio luego del '<')

< iframe class="marcoOculto" src="/aplicacion/action/confirmPopUp" name="popUpImpresion" id="popUpImpresion" onload="imprimoFrame()">
Su navegador no soporta IFrame
< /iframe>


3.-La class marcoOculto de css tiene lo siguiente:

/*oculta un iframe, en realidad pone ancho y alto a 0*/
iframe.marcoOculto{
border:none;
width:0em;
height:0em;
}


4.-El action /aplicacion/action/confirmPopUp lo que hace es llevar a la tile aplicacion.respuestaHTML que en realidad es la página html a imprimir. En realidad, se podía haber colocado la página directamente, pero esta forma es más elegante.



detectando navegador con js

/*Función que detecta el tipo de navegador: firefox=1, ie7=2, ie6=3.*/

function tipoNavegador(){
var version=0;
if (window.XMLHttpRequest) {
if(document.all){
//IE7
version=2;
}else{
//mozilla, safari, opera 9, etc
version=1;
}
} else {
// IE6, o viejos navegadores
version=3;
}
return version;
}

Comenzando

Hoy ¡por fin! me he dignado a crear un blog para dejar constancia de cosas con las que me topo en mi trabajo, sobretodo con java, es mi manera de colaborar a la "transmisión del conocimiento" porque si yo me baso en la red para buscar información creo que tengo que aportar mi granito de arena también ;).

VRS