Gestione avanzata eccezioni!

La gestione delle eccezioni è sempre un problema, con questo mini framework è possibile  proteggere il codice “pericoloso” in un’apposita struttura che faciliterà la gestione delle eccezioni o che permetterà di utilizzare metodi con eccezioni checked senza il blocco try/catch e senza perdere l’eventuale eccezione scatenata!
Tip fornito dal sig. S.Fago

/**
* Classe d’utilità per uso dei TryMethods…
*/
public class ExceptionUtil {
  private ExceptionUtil() {}

  public static Object execute(TryMethod method,java.util.Collection args){
   try {
          return method.execute(args);
       }catch (Exception ex) { return ex;  }
    }
}//end

/**
 * Interfaccia che stabilisce il contratto di un TryMethod da implementare per le 
 * RuntimeException… 
 */
public interface TryMethod{
   public Object execute(java.util.Collection args);
}

/**
* Implementazione di TryMethod per le checked exception…
*/
public class ReflectiveMethod implements TryMethod{
    private Object target;
    private String methodName;
    private Class[] paramTypes;

    public void init(Object target, String methodName, Class [] paramTypes){
     this.target = target;
     this.methodName = methodName;
     this.paramTypes = paramTypes;
    }

    public Object execute(java.util.Collection args){
     try {
          Class clazz = target instanceof Class?(Class)target:target.getClass();
          return (clazz.getDeclaredMethod(methodName,paramTypes)).invoke(  (target instanceof Class?null:target),args.toArray());
     }catch (java.lang.reflect.InvocationTargetException iex){return iex.getTargetException();}catch (Exception ex) {return ex;}
    }
  }//end

Un semplice blocco note

La class java allegata implementa un semplice blocco note, tipo quello di Windows, capace di gestire, grazie ai flussi di I/O messi a disposizione da java, i file di testo (carica/salvataggio).Nello sviluppo dell'applicazione si è deciso di non utilizzare massicciamente le opzioni grafiche delle JFrame, questo per mettere in rilevanza le potenzialità dei flussi di java.
Tip fornito dal sig. A.Avolio

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;

public class BloccoNotes implements WindowListener, ActionListener{

  //Istanze della classe
  private Frame finestra;
  private TextArea areaTesto;

  //Costruttore della classe

   public BloccoNotes(Frame f, TextArea t) {
     finestra = f;
     areaTesto = t;
   }

  //Gestione della grafica

  // Metodi non implementati dell'interfaccia WindowListener
  public void windowActivated(WindowEvent evt) {}
  public void windowDeactivated(WindowEvent evt) {}
  public void windowDeiconified(WindowEvent evt) {}
  public void windowIconified(WindowEvent evt) {}
  public void windowOpened(WindowEvent evt) {}

  // Metodi implementati dell'interfaccia WindowListener
  public void windowClosed(WindowEvent evt) {
    System.exit(0);
  }

  public void windowClosing(WindowEvent evt) {
    finestra.dispose();
  }

  // Metodo acoltatore ha il computo di ascoltare i comandi
  public void actionPerformed(ActionEvent evt) {
    String comando = evt.getActionCommand();
    //gestione dei vari eventi
    if (comando.equals("Esci")) {
      finestra.dispose();
    } else if (comando.equals("Apri")) {
      areaTesto.setText("");
      FileDialog d = new FileDialog(finestra, "Apri documento", FileDialog.LOAD);
      d.setVisible(true);
      if (d.getFile() != null) {
        try {
          String line;
          BufferedReader in = new BufferedReader(new FileReader(d.getDirectory() + File.separator + d.getFile()));
          while ((line = in.readLine()) != null)
            areaTesto.append(line + "\n");
        } catch (Exception e) {
          System.out.println("Errore: " + e);
        }
      }
    } else if (comando.equals("Salva con nome...")) {
      FileDialog d = new FileDialog(finestra, "Salva documento con nome", FileDialog.SAVE);
      d.setVisible(true);
      PrintWriter fout;
      String Stringa=areaTesto.getText();
      try{
        fout=new PrintWriter(new FileWriter(d.getDirectory()+File.separator+d.getFile()));
        StringTokenizer st=new StringTokenizer(Stringa,"\n"); //E' importante per gestire la pressione dell'invio
        while (st.hasMoreTokens())
          fout.println(st.nextToken());
        fout.close();
      }catch(Exception e){}
  }
}

  /** Metodo Main */
  public static void main(String[] args) {
    Frame f = new Frame("My blocco note ");
    TextArea t = new TextArea();
    BloccoNotes n = new BloccoNotes(f, t);
    MenuBar mb = new MenuBar();

    // Preparazione menù file il menu File
    Menu menu = new Menu("File");
    mb.add(menu);
    menu.add("Apri");
    menu.add("Salva con nome...");
    menu.addSeparator();
    menu.add("Esci");

    menu.addActionListener(n);

    // Prepara la finestra
    f.addWindowListener(n);
    f.setMenuBar(mb);
    f.add(t);
    f.setSize(400, 500);
    f.setVisible(true);
  }
} // BloccoNotes

Connessioni JDBC condivise

La libreria proposta, tramite poche istruzioni, consente di accedere ad un insieme di connessioni  jdbc da poter utilizzare in maniera condivisa; questo perchè il pool dichiara, istanzia e gestisce le connessioni per noi, permettendo il riutilizzo delle stesse tramite un booleano indicante lo stato della connessione; al termine dell'elaborazione la connessione non viene chiusa ma semplicemente rilasciata; se alla richiesta di una connessione quelle attualmente in pool sono tutte occupate, e se il limite massimo di connessioni stabilito non è stato superato, ne verrà creataautomaticamente una nuova. Complementare a questo, un thread che si occupa di controllare periodicamente il pool per verificare se esiste qualche connessione non rilasciata oltre un tempo massimo stabilito.
Tutto questo e molto di più è ampiamente spiegato nel file readme allegato.
Tip fornito dal sig. R. Favaroni

Descrizione delle classi contenute nell’archivio Java connectionpool.jar

ConnectionItem				Bean che mappa la singola connessione.
ConnectionManager		Thread dedicato al controllo periodico del pool delle connessioni alla ricerca di connessioni appese.

ConnectionParameters		Bean che mappa i parametri acquisiti da file properties.

ConnectionPool				Gestore del pool di connessioni.

MaxNumberConnectionException	Eccezione sollevata per la richiesta di connessioni superiori al limite stabilito.

Tester		Utility per effettuare stress test e benchmark fra connessioni in pool e connessioni singole.

PropertiesFileHandler			Wrapper per la lettura di file properties.

Ordinare un array bidimensionale

Il tip proposto consente di ordinare alfabeticamente un array bidimensionale, in questo caso formato  da 5 righe e 4 colonne (nome = newString[5][4]) ma può essere molto più grande. Il confronto è fatto dal primo elemento di ogni riga come se si trattasse di un array monodimensionale, mentre lo scambio avviene di tutta la riga. L'ordinamento può essere fatto prendendo in considerazione altri elementi delle colonne. Nell'esempio le righe risultano ordinate considerando per il confronto la prima colonna, se si vogliono ordinare le righe tenendo conto della seconda colonna sostituire nome[k][0]  con nome[k][1]  all'interno dell'unica istruzione condizionale if.
Tip fornito dal sig. G.Urso

import java.io.PrintStream;
public class Ordinamento
{
public Ordinamento()
{
nome = new String[5][4];
nome[0][0] = "Rossi Paolo ";
nome[0][1] = "Garibaldi n\260 34 ";
nome[0][2] = "Roma ";
nome[0][3] = "00100 ";
nome[1][0] = "Rossi Mario ";
nome[1][1] = "Mazzini n\260 14 ";
nome[1][2] = "Milano ";
nome[1][3] = "20100 ";
nome[2][0] = "Rossi Francesca ";
nome[2][1] = "Napoleone n\260 121 ";
nome[2][2] = "Milano ";
nome[2][3] = "20100 ";
nome[3][0] = "Rossi Giovanni ";
nome[3][1] = "Lincolm n\260 12 ";
nome[3][2] = "Torino ";
nome[3][3] = "10100 ";
nome[4][0] = "Rossi Alberto ";
nome[4][1] = "Cattaneo n\260 176 ";
nome[4][2] = "Bologna ";
nome[4][3] = "40100 ";
System.out.println(" SCRITTURA DISORDINATA ALFABETICAMENTE");
System.out.println(" ");
System.out.println("Cognome e nome Via Citt\340 C.A.P. ");
System.out.println(" ");
for(x = 0; x < 5; x++)
{
System.out.println(" ");
for(j = 0; j < 4; j++)
System.out.print(nome[x][j]);
}

for(int i = nome.length - 1; i >= 0; i--)
{
for(int k = 1; k <= i; k++)
if(nome[k][0].compareTo(nome[k - 1][0]) < 0)
{

nomeb = new String[5];
for(int l = 0; l < 4; l++)
{
nomeb[l] = nome[k - 1][l];
nome[k - 1][l] = nome[k][l];
nome[k][l] = nomeb[l];
nomeb[l] = "";
}
}
}

System.out.println(" ");
System.out.println(" ");
System.out.println(" ");
System.out.println(" SCRITTURA ORDINATA ALFABETICAMENTE");
for(x = 0; x < 5; x++)
{
System.out.println(" ");
for(j = 0; j < 4; j++)
System.out.print(nome[x][j]);
}
}

public static void main(String args[])
{ Ordinamento ordinamento = new Ordinamento(); }

int x;
int j;
String nome[][];
String nomeb[];
}

Passare valori tra pagine web

Il codice JavaScript  permette di passare i valori di variabili tra pagine  senza  l'uso  di  php,  cgi o cookies semplicemente sfruttando l'url della pagina. La pagina di "partenza" quando chiama la pagina “ricevente" il valore deve rispettare la seguente sintassi "indirizzo?variabile1=valore1&variabile2=valore2&variabile3=valore3", ovvero quella che,  generalmente, viene utilizzata dai form utilizzando il metodo "GET". Per  poter  ottenere il valore di una variabile è sufficiente chiamare la  funzione  leggivarabile passandole come parametro semplicemente il nome della variabile stessa. In allegato un file ".htm" d’esempio che mostra il funzionamento dello script anche in coppia con i form. 
Tip fornito dal sig. I. Scarabello

function leggivariabile(variabile) {
               // variabile contiene il nome della variabile
         var indirizzo = window.location.toString() + "&";
               // indirizzo contiene l'indirizzo della pagina nella forma
               // "indirizzo?variabile1=valore1&variabile2=valore2&variabile3=valore3&"
         var posizionenome=indirizzo.indexOf(variabile + "=");
               // trova la posizione in cui e' memorizzata la variabile
         if (posizionenome==-1) return "";
               // se restituisce -1 la variabile non c'e'! :(
         var sottostringa=indirizzo.substring(posizionenome);
               // taglia tutto quello che c'e' prima della variabile
         var inizio=sottostringa.indexOf("=");
               // trova l'uguale dopo il quale si trova il valore
         var fine=sottostringa.indexOf("&");
               // trova la & che indica dove finisce il valore
         var variabile=sottostringa.substring(inizio + 1, fine);
               // assegna a variabile il valore contenuto tra = e &!

        return variabile;
}

Visualizzare un file RTF in una pagina Web

Il problema risolto da quest’applet nasce da una reale esigenza: in un database venivano memorizzati dei file RTF, inclusi, quindi, tutti i tag del formato. Dovendo procedere ad una pubblicazione su Internet di questi dati e non riuscendo a trovare un “convertitore” RTF->TXT o RTF->Html (o meglio, c’era un componente ASP ma il prezzo era di circa 600 dollari!), ho deciso di utilizzare Java e creare un’applet personalizzata.
Tutto è affidato al package javax.swing.text.rtf…stando alla documentazione, questo package non è stato sviluppato dal team Java ed il supporto non è ancora ottimale, infatti ho provato a visualizzare un RTF con inclusa un’immagine, ma non è stato visualizzato. Spero, comunque, che il tip possa essere utile. In allegato potrete trovare il sorgente, la classe ed una pagina html di esempio in cui è stato inserito “manualmente” il codice RTF. In realtà l’applet è stata concepita per prendere come parametro il codice RTF che dovrebbe essere passato con una sintassi in stile ASP, qualcosa del tipo

<param name = “RTF”  value = “ <% = nome_della_variabile %> “ >

in cui la variabile in questione, in questo caso, è un result-set.

L’altro parametro è “bground” che prende una sequenza esadecimale per definire lo sfondo  dell’applet. Il funzionamento è uguale alla definizione dei colori in HTML, tranne per il fatto che non bisogna inserire il “#” davanti.

Tip fornito dal sig. G.Esposito

import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.rtf.*;

/**
 * <p>Titolo: RTFView</p>
 * <p>Descrizione: Visualizza RTF in pagine Web</p>
 * @author Gianluca Esposito (giaesp@tiscali.it)
 * @version 0.11.17.03
 */

public class RTFView
    extends JApplet {

  private boolean isStandalone = false;
  JScrollPane rtfScroller = new JScrollPane();
  JTextPane rtfPane = new JTextPane();

  String RTFText;
  int bground;

  public String getParameter(String key, String def) {
    return isStandalone ? System.getProperty(key, def) :
        (getParameter(key) != null ? getParameter(key) : def);
  }

  public RTFView() {
  }

  public void init() {
    try {
      RTFText = this.getParameter("RTF",
                                  "Nessuna informazione da visualizzare.");
    }
    catch (Exception e) {
      e.printStackTrace();
    }
    try {
      bground = Integer.parseInt(this.getParameter("bground", "FFFFFF"), 16);
    }
    catch (Exception e) {
      e.printStackTrace();
    }
    try {
      jbInit();
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }

  private void jbInit() throws Exception {
    // this.setSize(new Dimension(width,height));
    rtfPane.setEditorKit(new RTFEditorKit());
    rtfPane.setEditable(false);
    rtfPane.setCaretPosition(0);
    rtfPane.setText(RTFText); // Inserimento del testo RTF
    this.getContentPane().add(rtfScroller, BorderLayout.CENTER);
    rtfScroller.getViewport().add(rtfPane, null);
    rtfPane.setBackground(new Color(bground));
    rtfScroller.setBackground(new Color(bground));
    this.setVisible(true);
  }

  public void start() {
  }

  public void stop() {
  }

  public void destroy() {
  }

  public String getAppletInfo() {
    return "RTFView 0.11.17.03 (Gianluca Esposito - giaesp@tiscali.it)";
  }

  public String[][] getParameterInfo() {
    String[][] pinfo = {
        { "RTF", "String", "Corpo dell'RTF"},
        { "bground", "hex int", "Colore di sfondo - Inserire sequenza esadecimale (come nell'HTML, ma senza \"#\")"},
    };
    return pinfo;
  }

  static {
    try {
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    }
    catch (Exception e) {
    }
  }
}