martes, 21 de agosto de 2012

Versión de Java de un .class


Hace poco tuve un pequeño problema con un código que nos enviaron ya compilado. A la hora de hacer deployment en el servidor obteníamos una excepción de tipo:

javax.servlet.ServletException: Bad version number in .class file

Según lo que leí la excepción se da porque la clase fue compilada con una versión más alta de Java que la que corre en la  máquina virtual. Por ejemplo que la clase fue compilada en Java 6 y la máquina virtual corre Java 5.

Para confirmar esto indague un poco en Google como averiguar la versión de una clase. Para ello existe un comando: javap -verbose ClassName

(El .exe se puede encontrar en la carpeta bin del JDK)

Es conveniente guardar en un archivo el resultado del comando pues tira bastante información. Dentro de esa información hay que buscar la combinación de minor y major version que se encuentra al puro comienzo para determinar la versión de Java utilizada.

major  minor Java platform version 
45       3           1.0
45       3           1.1
46       0           1.2
47       0           1.3
48       0           1.4
49       0           1.5
50       0           1.6

lunes, 20 de agosto de 2012

Provincias, cantones y distritos para seleccionar

Basado en una entrada anterior donde puse a disposición un script para crear las tablas que representan la estructura de provincias, cantones y distritos, he creado un script PHP que genera unos arreglos en JavaScript para poder utilizarlos en selectores de manera que carguen dinámicamente según la selección anterior. Básicamente, si selecciona una provincia, cargue los cantones de esa provincia, y si selecciona un cantón, cargue los distritos de ese cantón.

El script en PHP sería este:

<?php
 mysql_connect("localhost","root","") or die("Unable to connect to SQL server");
 @mysql_select_db("data_base_name") or die("Unable to select database"); 
  
 $provincias_result = mysql_query("select * from PROVINCIA_CR");
  
 echo "var p=new Array();var c=new Array();var d=new Array();";
 while ($provincia_row = mysql_fetch_row($provincias_result)) {
   
  echo "p[" . $provincia_row[0] . "]='" . $provincia_row[1] . "';";
   
  $cantones_result = mysql_query("select * from CANTON_CR where codigo_provincia = "
   . $provincia_row[0]);
   $canton_line = "c[". $provincia_row[0] . "]='"; 
   $distrito_lines = "";
   while ($canton_row = mysql_fetch_row($cantones_result)) {
    $canton_line = $canton_line . $canton_row[2] ."@" .  $canton_row[1] . "~";
     
    $distritos_result = mysql_query("select * from DISTRITO_CR where codigo_canton = "
     . $canton_row[0]);
      
    $distrito_line = "d[". $canton_row[1] . "]='";   
    while ($distrito_row = mysql_fetch_row($distritos_result)) {
      $distrito_line .= $distrito_row[2] ."@" .  $distrito_row[1] . "~";
    }
    $distrito_line=substr_replace($distrito_line ,"",-1); // Remueve último caracter.
    $distrito_lines .= $distrito_line . "';";
   }
   $canton_line=substr_replace($canton_line ,"",-1); // Remueve último caracter.
   echo $canton_line . "';";
   echo $distrito_lines;   
 }
?>
Este script genera un código como este (también dejo a disposición el script generado):
var p=new Array();var c=new Array();var d=new Array();p[1]='San José';c[1]='San José@1~Escazú@1~Desamparados@1~Puriscal@1~Tarrazú@1~Aserrí@1~Mora@1~Goicoechea@1~Santa Ana@1~Alajuelita@1~Vasquez de Coronado@1~Acosta@1~Tibás@1~Moravia@1~Montes de Oca@1~Turrubares@1~Dota@1~Curridabat@1~Pérez Zeledón@1~León Cortés@1';d[1]='Carmen@101~Merced@101~Hospital@101~Catedral@101~Zapote@101~San Francisco de Dos Ríos@101~Uruca@101~Mata Redonda@101~Pavas@101~Hatillo@101~San Sebastián@101';d[1]='Escazú@102~San Antonio@102~San Rafael@102';d[1]='Desamparados@103~San Miguel@103~San Juan de Dios@103~San Rafael Arriba@103~San Antonio@103~Frailes@103~Patarrá@103~San Cristóbal@103~Rosario@103~Damas@103~San Rafael Abajo@103~Gravilias@103~Los Guido@103';d[1]='Santiago@104~Mercedes Sur@104~Barbacoas@104~Grifo Alto@104~San Rafael@104~Candelaria@104~Desamparaditos@104~San Antonio@104~Chires@104';d[1]='San Marcos@105~San Lorenzo@105~San Carlos@105';d[1]='Aserrí@106~Tarbaca o Praga@106~Vuelta de Jorco@106~San Gabriel@106~La Legua@106~Monterrey@106~Salitrillos@106';d[1]='Colón@107~Guayabo@107~Tabarcia@107~Piedras Negras@107~Picagres@107';d[1]='Guadalupe@108~San Francisco@108~Calle Blancos@108~Mata de Plátano@108~Ipís@108~Rancho Redondo@108~Purral@108';d[1]='Santa Ana@109~Salitral@109~Pozos o Concepción@109~
...
Con ese código se puede agregar lógica JavaScript, sazonada con JQuery, para cargar las opciones dinámicamente:

Código en GitHub

<html>
<head>
 <script src="distritos.js" type="text/javascript"></script>
 <script src="jquery-1.7.1.min.js" type="text/javascript"></script> 
 <script type="text/javascript">  
  var separator1 = "~";
  var separator2 = "@";
  
  function cargarProvincias(provinciaId) {
   $("#" + provinciaId).append($("<option></option>")
    .attr("value", -1).text("Elija una provincia"));  
   for (var key in p) {
    $("#" + provinciaId).append($("<option></option>")
     .attr("value", key).text(p[key]));
   }
  }
  
  function cargarCantones(provincia, cantonId) {
   var provinciaSelectedValue =  $(provincia).val();
   $("#" + cantonId + " option").remove();
   
   if(provinciaSelectedValue != -1) {     
    $("#" + cantonId).append($("<option></option>")
     .attr("value", -1).text("Elija un cantón")); 
    
    var cantones = c[provinciaSelectedValue].split(separator1);
    
    for (var i=0; i < cantones.length; i++) {
     var cantonValuePair = cantones[i].split(separator2);
     $("#" + cantonId).append($("<option></option>")
     .attr("value", cantonValuePair[1]).text(cantonValuePair[0]));
    }    
   } else {
    $("#" + cantonId).append($("<option></option>")
     .attr("value", -2).text("Elija una provincia"));
   }
   cargarDistritos($("#" + cantonId), "distritos");
  }
  
  function cargarDistritos(canton, distritoId) {
   var cantonSelectedValue =  $(canton).val();
   $("#" + distritoId + " option").remove();
   
   if(cantonSelectedValue > 0) {      
    $("#" + distritoId).append($("<option></option>")
     .attr("value", -1).text("Elija un distrito")); 
    
    var distritos = d[cantonSelectedValue].split(separator1);
    
    for (var i=0; i < distritos.length; i++) {
     var distritoValuePair = distritos[i].split(separator2);
     $("#" + distritoId).append($("<option></option>")
     .attr("value", distritoValuePair[1]).text(distritoValuePair[0]));
    }    
   } else if(cantonSelectedValue == -1){
    $("#" + distritoId).append($("<option></option>")
     .attr("value", -1).text("Elija un cantón")); 
   } else if(cantonSelectedValue == -2){
    $("#" + distritoId).append($("<option></option>")
     .attr("value", -1).text("Elija una provincia")); 
   }
  }  
 </script> 
</head>

<body onload="cargarProvincias('provincias')">
 <select id="provincias" onchange="cargarCantones(this, 'cantones');"></select>
 <select id="cantones" onchange="cargarDistritos(this, 'distritos');"><option value="-2">Elija una provincia</option></select>
 <select id="distritos"><option value="-2">Elija una provincia</option></select>
</body>
</html>

Resultado Final:

lunes, 23 de julio de 2012

CakePHP: Carga dinámica de select input con JSON

Continuando con mis experiencias en este aprendizaje del framework CakePHP, quiero poner a disposición una receta en la cual tardé bastante en encontrar y personalizar, de cómo preparar una carga dinámica de un select box a partir de una selección anterior.

En este ejemplo cargo las opciones de raza a partir de una selección previa de una especie.

Ingredientes:


1. Función en el controlador para listar las especies (primer select box):

public function add() {  
   if ($this->request->is('post')) {
       // Código para salvar el anuncio.
    } else {
        $especie = new Especie();         
        $especies = $especie->find('list', array(       
     'fields' => array('Especie.id', 'Especie.nombre')
 ));
        $this->set('especies', $especies);         
    }
}

2. Código del formulario:
Form->create('Anuncio');
 
 echo $this->Form->input('especie', array(
     'type'    => 'select',
     'options' => $especies,
     'empty'   => 'Elija una especie'
 ));
 echo $this->Form->input('raza', array(
     'type'    => 'select',
     'empty' => 'Elija una especie'
 ));    
 echo $this->Form->end('Guardar Anuncio');
?>

3. Función en el controlador para retornar un JSON con las razas pertenecientes a la especie:

    public function getRazasByEspecie() {
     if ($this->request->is('ajax')) { 
      $idEspecie = $this->params['data']['idEspecie'];
       
      $raza = new Raza();
      $razas = $raza->find('all',array(
       'fields' => array('Raza.id', 'Raza.nombre'), 
       'conditions'=>array('Raza.id_especie'=>$idEspecie)));
      
      $this->RequestHandler->respondAs('json');
      $this->autoRender = false;      
      echo json_encode ( $razas );      
     }
    }

Preparación:

Agregar el código JavaScript que una (binding) la siguente lógica al evento de modificación del primer select box. La función hace un llamado Ajax al controlador para pedir las razas. Estas son retornadas en formato JSON el cual es procesado para agregar las nuevas opciones del segundo select box.
$(document).ready(function(){

 $('#AnuncioEspecie').change(function(){
  var selected = $(this).val();
    
  $.ajax({
   type: "POST",
   url: '/Anuncios/getRazasByEspecie',
   data: "idEspecie="+selected,
   dataType: 'json',
   success: function(data){
    
    $('#AnuncioRaza option').remove();
    var $el = $("#AnuncioRaza");
    if (data.length > 1) {
     $el.append($("")
       .attr("value", -1).text("Elija una raza"));
    }
    $.each(data, function(i,items){
     $el.append($("")
       .attr("value", items.Raza.id).text(items.Raza.nombre));          
    });    
   }
  });
 });
});


Consumase al gusto :D!

miércoles, 11 de julio de 2012

ASP: Redireccionamiento para un dominio específico

Si se desea redireccionar el acceso a una página para un dominio específico, en caso hayan varios dominios apuntando al mismo código:
<%
If Request.ServerVariables("SERVER_NAME") = "www.mysite.com" Then
Response.redirect "http://www.redirect.com"
End If
%>