Tips&Tricks I trucchi del mestiere

 

Compilare le classi ôal voloö


Il tip proposto riguarda la compilazione a run-time, di classi java in modo veloce ed efficiente usando una classe delle librerie del java2 sdk in alternativa al metodo, pi∙ intuitivo ma meno elegante, che prevede la creazione di un processo separato e l' invocazione mediante la exec del compilatore javac.
UnÆapplicazione pu≥, quindi, creare i propri file java e ottenerne una compilazione per poi caricane le classi appena create tramite la Reflection; ci≥ garantisce la disponibilitα di classi da essa stessa create. La libreria da includere Φ la \lib\tools.jar presente nella directory del Java 2 SDK.
Tip fornito dal sig. M.Pace

import java.io.*;
import java.util.*;

public class Compilertip {
  public static void main(String args[]) throws IOException  {
       if(args.length==0){      
          System.out.println("Linea di comando: java Compilertip file1 file2 ecc");    
       }else{
          Compile(args);
       }            
   }

 /*Compila i file i cui nomi sono nel vettore fornito come parametro*/
   static public boolean Compile(String[] filenames){
        try{
           int filecompilati = 0;       
           
           for(int i=0;i<filenames.length;i++){
              String fname = filenames[i]; 
              String sourceFile =  this.currentpath+""+fname[i]+".java";
              int compileReturnCode = com.sun.tools.javac.Main.compile(new String[] 
{sourceFile});
              if (compileReturnCode == 0) {
                System.out.println("File "+ filenames[i] + " compilato con successo.");
                filecompilati++;
              }else{
                System.out.println("Errore nella compilazione di "+  filenames[i] + ". Termino.");
                return false;         
              }
            }//for
       
             if(filecompilati == filenames.length){
               System.out.println("Tutti i file ("+filecompilati+") compilati con successo.");
               return true;
             }     
             catch(Exception e){
             /*... gestione dell' errore...*/   
             }    
             
             return false;
   }    
   }                                  
/*
      javac -classpath  c:\j2sdk1.4.2\lib\tools.jar Compilertip.java
      java  -classpath  c:\j2sdk1.4.2\lib\tools.jar Compilertip.java
*/



Input bufferizzato


Un tip Java che risolve un problema spesso riscontrato, quello della gestione dell'input da tastiera non bufferizzato e con echo disabilitato (utile anche per l'inserimento di password).
A questo scopo faremo uso dei JNI (Java Native Interface) di Java, che offre al programmatore la possibilitα di far interagire codice C/C++ con il codice Java in maniera relativamente semplice.
Tip fornito dal sig. C. Sicilia

package it.kya.io;
import java.io.IOException;
public class KeyBoard
{
	static
	{
		System.loadLibrary("KeyBoard");
	}
	public static native int read() throws IOException;
}

La classe KeyBoard fornisce lÆinterfaccia necessaria al nostro scopo, dichiarando il metodo read.
Il secondo passo Φ quello di compilare la classe con il semplice comando:


javac KeyBoard.java

La compilazione creerα la classe KeyBoard.class nel package it.kya.io.
Il terzo passo Φ quello di creare lÆheader per le funzioni C da implementare, a questo scopo useremo il tool javah, presente nella cartella bin del jdk:


javah ûjni ûo KeyBoard.h it.kya.io.KeyBoard

Questa procedura genererα il file KeyBoard.h del tutto simile a quanto proposto:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include 
/* Header for class it_kya_io_KeyBoard */

#ifndef _Included_it_kya_io_KeyBoard
#define _Included_it_kya_io_KeyBoard
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     it_kya_io_KeyBoard
 * Method:    read
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_it_kya_io_KeyBoard_read
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

A questo punto non ci rimane che implementare le funzioni in codice C, il prossimo passo sarα, quindi, quello di creare un file KeyBoard.c contenente le funzioni dichiarate nellÆheader.
Bisogna dire che una funzione scritta in C non Φ portabile e richiede quindi che venga ricompilata sui diversi sistemi operativi e visto che la portabilitα Φ un punto di forza di Java bisognerα, quantomeno, fornire una libreria per Windows e una per Linux.
Essendo LÆI/O generalmente legato al sistema operativo, in particolare la lettura dalla tastiera, avremo bisogno di librerie diverse per i due sistemi. Per Windows useremo conio.h, per Linux curses.h, utilizzeremo le macro per gestire una compilazione sul medesimo file, quindi nel file KeyBoard.c scriveremo:

#if defined _WIN32
#	include 
#elif defined __linux__
#	include 
#else
#	error Operating system is undefined or unknown!
#endif

#include 
#include "KeyBoard.h"

JNIEXPORT jint JNICALL Java_it_kya_io_KeyBoard_read
	(JNIEnv *env, jobject obj)
{
	jint ch;
#if defined _WIN32
	ch = _getch();
#elif defined __linux__
	initscr();
	cbreak();
	noecho();
	ch = getchar();
	echo();
    endwin();
	if(ch == ERR)
	{
		jclass newExc = (*env)->FindClass(env, "IOException");
		if (newExc != NULL)
		{
			(*env)->ThrowNew(env, newExc, "I/O Input error");
		}
		(*env)->DeleteLocalRef(env, newExc);
	}
#endif
	return ch;
}



La convalida della partita IVA


Programmando in ambito web ( JSP ecc.), ci si trova spesso a dover controllare la correttezza di alcuni campi, inseriti dall'utente.
Ci≥, spesso, porta alla perdita di non poco tempo, per lo sviluppo di funzioni di controllo specializzate per il campo. In genere i pi∙ laboriosi sono il codice fiscale (di cui una soluzione Φ giα stata pubblicata) e la Partita Iva.
La funzione qui riportata esegue un controllo su una stringa contenete una Partita Iva e restituisce valore true se essa Φ valida, false altrimenti.
Tip fornito dal sig. G. Sanfilippo

boolean checkValidPartitaIva(String PartitaIva)
{ int Somma01 = 0; int Somma02 = 0; int CheckNumber;
  if (PartitaIva.length() != 11) return false;
  try 
  { if(Float.parseFloat(PartitaIva) < Float.parseFloat("0")) return false;
  }  catch (NumberFormatException NFE) {NFE.printStackTrace(); return false;}
  for (int i = 0; i < 9; i += 2) 
  { CheckNumber = Integer.parseInt(""+PartitaIva.charAt(i));  
    Somma01 += CheckNumber;  
    CheckNumber = Integer.parseInt(""+PartitaIva.charAt(i+1));  
    Somma01 += Math.floor(CheckNumber/5) + (CheckNumber << 1) % 10; 
  }
  Somma02 = 10 - (Somma01 % 10);
  CheckNumber = Integer.parseInt(""+PartitaIva.charAt(10));
  if (Somma02 != CheckNumber) return false; else return true;
}