venerdì 27 dicembre 2013

Localizzazione 2/2

L'utilizzo del locale in Java prevede la possibilità di sfruttare 2 classi che derivano dalla classe abstract ResourceBundle e che sono:
  • La classe concreta PropertyResourceBundle che prevede il supporto dei locale tramite file di properties;
  • La classe astratta ListResourceBundle che può essere estesa per aggiungere il supporto ad uno specifico locale effettuando l'override del metodo getContents() che torna un Object[][] con la lista delle chiavi e valori necessari.
ESEMPIO UTILIZZO PROPERTYRESOURCEBUNDLE

Creiamo un Java Project con una classe main di questo tipo:


package it.bundles;
import java.util.Locale;
import java.util.ResourceBundle;
public class CiaoLocalizzato {
	public static void main(String[] args){
Locale.setDefault(Locale.FRANCE);
Locale current=Locale.getDefault();
System.out.println(String.format("Locale %s %s %s", current.getDisplayName(),
current.getLanguage(),current.getCountry()));
ResourceBundle bundle=ResourceBundle.getBundle("it.localizzazione.ResourceBundle",current);
System.out.println(bundle.getString("greetings"));
	}
}


Quindi definiamo un package it.localizzazione al cui interno mettiamo i nostri file di properties.
La regola base è che il file deve essere presente nel classpath per poter consentire il caricamento a runtime delle proprietà.
Nel package avremo ad esempio i file :
  •  ResourceBundle.properties (il default nel caso non si trovi il locale giusto);
  • ResourceBundle_it.properties (per l'estensione italiana);
  • ResourceBundle_fr.properties (per l'estensione francese utilizzata in questo caso).
I file saranno semplici file di properties con la chiave greetings mappata ai valori "Hello" "Ciao" oppure "Bonjour!" a seconda della tipologia di locale.
Mandando in esecuzione il programma di volta in volta sarà stampato il valore a seconda del locale (sarà stampato Hello se il locale settato non ha un file di properties di riferimento).



ESEMPIO UTILIZZO LISTRESOURCEBUNDLE 

In questo caso dobbiamo definire 2 classi che estendono ListResourceBundle

package it.bundles;
import java.util.ListResourceBundle;
public class ResBundle extends ListResourceBundle {
	static final Object[][] contents={{"nome","ARSENAL"},{"anno","1886"},{"scudetti","13"}};
	@Override
	protected Object[][] getContents() {
		return this.contents;
	}

}



package it.bundles;
import java.util.ListResourceBundle;
public class ResBundle_it_IT extends ListResourceBundle {
	static final Object[][] contents={{"nome","INTER"},{"anno","1908"},{"scudetti","18"}};
	@Override
	protected Object[][] getContents() {
		return this.contents;
	}

}


Quindi nel nostro main come al solito:


package it.bundles;
import java.util.Locale;
import java.util.ResourceBundle;
public class TestResBundle {
	public static void main(String[] args) {
		Locale.setDefault(Locale.CANADA);
		Locale l=Locale.getDefault();
		ResourceBundle rb=ResourceBundle.getBundle("it.bundles.ResBundle",l);
		System.out.println(rb.getString("nome"));
		System.out.println(rb.getString("anno"));
		System.out.println(rb.getString("scudetti"));
	}
}


Giocando con il settaggio del default locale possiamo leggere i dati dalla classe localizzata di nostro interesse.

Localizzazione 1/2

Un oggetto di tipo Locale rappresenta un insieme di caratteristiche peculiari di un paese, ossia linguaggio, cultura, formattazione di numeri e di date.
La classe java.util.Locale possiede alcune importanti proprietà riferite a 3 entità fondamentali, il nome del paese, il nome della lingua e il nome del cosiddetto VARIANT, che indica la variazione del linguaggio all'interno del paese (praticamente il dialetto):
  • getCountry() che torna il codice del paese;
  • getDisplayCountry() che torna il nome del paese;
  • getLanguage() che torna il codice del linguaggio del paese;
  • getDisplayLanguage() che torna la descrizione del linguaggio del paese;
  • getVariant() che torna il variant code;
  • getDisplayVariant() che torna la descrizione del variant.
 Con questo semplice codice possiamo avere informazioni sui Locale presenti nella nostra JVM.
Oltre alle 3 informazioni fondamentali su paese-linguaggio-dialetto abbiamo anche informazioni aggiuntive in alcuni linguaggi (script ed extensions) che vedremo poi negli esempi.


public static void main(String[] args) {
  Locale[] lista=Locale.getAvailableLocales();
  System.out.println(Locale.getDefault());
  System.out.printf("Numero locale presenti %s",lista.length);
  System.out.println();
  for(Locale l:lista){
   //if(l.getLanguage().equals("it"))
   System.out.println(l+" - "+l.getDisplayName());
   
  }
  

 }


L'output può essere filtrato se si inserisce il commento, stampando soltanto quello che corrisponde al country code desiderato.
Se ad esempio mettiamo "en" nel filtro avremo il seguente output:

it_IT
Numero locale presenti 156
en_MT - inglese (Malta)
en_GB - inglese (Regno Unito)
en_CA - inglese (Canada)
en_US - inglese (Stati Uniti)
en_ZA - inglese (Sudafrica)
en - inglese
en_SG - inglese (Singapore)
en_IE - inglese (Irlanda)
en_IN - inglese (India)
en_AU - inglese (Australia)
en_NZ - inglese (Nuova Zelanda)
en_PH - inglese (Filippine)

I primi 2 caratteri rappresentano il codice del linguaggio, quindi abbiamo il codice del Paese (es en_GB ).
Ci possono poi essere anche il codice variant. Ad esempio abbiamo (se filtriamo per language "no") tra gli output questa stringa:
no_NO_NY ossia norvegese (Norvegia,Nynorsk)
Il Nyorsk è infatti un dialetto norvegese utilizzato da circa il 10-15% della popolazione norvegese.

In alcuni casi sono presenti anche gli script e le extension, ossia altre informazioni aggiuntive oltre al dialetto (variant)  . Ad esempio se scegliamo come codice "th" otteniamo tra gli altri risultati:
th_TH_TH_#u-nu-thai - thai (Thailandia,TH)


qui non abbiamo lo script ma abbiamo le extension, in questo caso u-nu-thai.
Per vedere un esempio di script possiamo provare il codice linguaggio "sr".
Vedremo in output ad esempio:
sr_ME_#Latn - serbo (Latino,Montenegro)

Latn è un esempio di script, deve essere  fatto da 4 lettere di cui la prima maiuscola (e. Latn,Cyrl).

domenica 22 dicembre 2013

Java implementazione pattern observer

Il pattern OBSERVER rientra nella categoria dei pattern "comportamentali".
Esistono 3 categorie principali di pattern:
  • CREAZIONALI ( es. SINGLETON, FACTORY, ABSTRACT FACTORY)
  • STRUTTURALI  (es. DECORATOR, PROXY, FACADE)
  • COMPORTAMENTALI (es. OBSERVER, STATE,STRATEGY)
Per realizzare questo pattern la classe che deve "segnalare" le modifiche agli osservatori dovrà estendere la classe java.util.Observable, mentre le classi che ricevono la segnalazione dovranno implementare l'interfaccia java.util.Observer che definisce il metodo  update.

Vediamo un semplice esempio.

CLASSE OBSERVABLE


package it.pattern;
import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
public class Lista extends Observable {
 private List<String> lista=new ArrayList<>();
 public List<String> getLista() {
  return lista;
 }
 public void addString(String elemento){
  setChanged();
  notifyObservers(elemento);
  lista.add(elemento);
 }
}


CLASSE OBSERVER

package it.pattern;
import java.util.Observable;
import java.util.Observer;
public class ListaObserver implements Observer {
 @Override
 public void update(Observable o, Object arg) {
  System.out.println("Aggiunto elemento "+arg);
 }
}


Vediamo di seguito un esempio di utilizzo:

package it.pattern;

public class Test {
 public static void main(String[] args) {
  Lista l=new Lista();
  l.addObserver(new ListaObserver());
  l.addString("dsjksdkjd");
  l.addString("dsddsds");

 }

}


Il risultato dell'esecuzione del codice sarà il seguente:

Aggiunto elemento dsjksdkjd
Aggiunto elemento dsddsds


domenica 8 dicembre 2013

Esempio zip file con Java 7

Di seguito un esempio su come zippare un file in Java utilizzando le features della Java7 in particolare:
  1. Il try with resources, che ci risparmia la fatica di dover chiudere gli stream aperti, basta dichiarare tutte le aperture nel blocco di parentesi tonde del try;
  2. Le suppressed exceptions, ossia la possibilità di farsi stampare nel catch anche tutte le altre eccezioni eventualmente riscontrate nel blocco delle parentesi tonde del try. 
Esempio


package it.varie;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipFile {
public static final int CHUNK=1024;
public static final String DIR="C:\\lav\\workspace\\wsTest\\Java7Cert\\src\\";
public static void main(String[] args) {
  if(args.length==0){
   System.err.println("Attenzione passare come parametro il nome file");
   System.exit(-1);
  }
  String fileName=args[0];
  String zipFileName=fileName+".zip";
  byte[] buffer=new byte[CHUNK];
  try( ZipOutputStream zipFile=new ZipOutputStream(new FileOutputStream(zipFileName));
    FileInputStream fis=new FileInputStream(DIR+fileName);
    )
    {
            zipFile.putNextEntry(new ZipEntry(zipFileName));
            int lenRead=0;
            while((lenRead=fis.read(buffer))>0){
             zipFile.write(buffer, 0, lenRead);
            }
    }
  catch(Exception e){
   System.out.println("Eccezione: "+e);
   System.out.println("Eventuali eccezioni soppresse");
   for(Throwable t: e.getSuppressed()){
    System.out.println(t);
   }
  }
 }
}