JSF2: valueChangeListerer e valori null

Problema: setto a null il valore di un inputText tramite jQuery, faccio submit della pagina e scatta la validazione tramite validatore custom. Se la validazione fallisce viene riportato nel campo messo a null l’ultimo valore valido precedente.

Causa: da una discussione trovata su http://stackoverflow.com/questions/3933786/jsf-2-bean-validation-validation-failed-empty-values-are-replaced-with-las pare sia un *bug* di Mojarra:

settando la proprietà nel web.xml:

<context-param>
    <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
    <param-value>true</param-value>
</context-param>

si verifica un bug in HtmlBasicRenderer#getCurrentValue() in Mojarra:

if (component instanceof UIInput) {
    Object submittedValue = ((UIInput) component).getSubmittedValue();
    if (submittedValue != null) {
        // value may not be a String...
        return submittedValue.toString();
    }
}

String currentValue = null;
Object currentObj = getValue(component);
if (currentObj != null) {
    currentValue = getFormattedValue(context, component, currentObj);
}
return currentValue;

Normalmente, il valore inviato è impostato su null quando il componente UIInput viene convertito e validato con successo. Quando JSF è in procinto di visualizzare nuovamente il valore, prima controlla se il valore inserito non sia null prima di procedere per visualizzare di nuovo il valore di modello. Tuttavia, con questo parametro di contesto, è nullo, invece di una stringa vuota quando non è valido e così sarà sempre visualizzare nuovamente il valore del modello originale quando si rimuove il valore iniziale di un campo obbligatorio.

Soluzione: la parte jQuery setta il valore *stringa vuota* invece di null (nel caso specifico la soluzione funziona perché il test sul valore è effettuato tramite il metodo di utilità org.apache.commons.lang3.StringUtils.isNotBlank sul valore dell’input).

[BIGNAMI] Design Patterns in Java – Parte 3

§INTERFACE PATTERNS§ – FACADE pattern

La programmazione OO permette di creare toolkits e sottosistemi di carattere generico, che possono poi essere sfruttati da applicazioni legate ad uno specifico dominio.
Tali sottosistemi espongono spesso interfacce complesse e molto diverse fra loro, l’intento del pattern FACADE è di fornire un’interfaccia che renda il sottosistema facile da usare, esponendo una interfaccia più semplice.

Una classe facade può avere tutti metodi statici, in questo caso è chiamata classe utility (in UML).

La classe JOptionPane (javax.swing package) è uno dei pochi esempi di facade contenuto nelle librerie di classi Java:
questa classe semplifica la creazione di un dialog box pop up.

[BIGNAMI] Design Patterns in Java – Parte 1

Il libro di riferimento è: Design Patterns in Java(TM) (Software Patterns Series) by Steven John Metsker.

Un pattern è *un modo per fare qualcosa*, una tecnica già sperimentata e consolidata per espletare un dato compito.

In modo analogo, un design pattern è un pattern che usa classi e metodi in un linguaggio object oriented per risolvere problemi noti.
Un pattern rappresenta una idea, non una particolare implementazione.

Si possono classificare i Design Patterns secondo i problemi che risolvono:
1. Interfacce (Interfaces)
2. Responsabilità (Responsibility)
3. Costruttori (Construction)
4. Operazioni (Operations)
5. Estensioni (Extensions)

In particolare:

  • Interfaces
    • ADAPTER
    • FACADE
    • COMPOSITE
    • BRIDGE
  • Responsibility
    • SINGLETON
    • OBSERVER
    • MEDIATOR
    • PROXY
    • CHAIN OF RESPONSIBILITY
    • FLYWEIGHT
  • Construction
    • BUILDER
    • FACTORY METHOD
    • ABSTRACT FACTORY
    • PROTOTYPE
    • MEMENTO
  • Operations
    • TEMPLATE METHOD
    • STATE
    • STRATEGY
    • COMMAND
    • INTERPRETER
  • Extensions
    • DECORATOR
    • ITERATOR
    • VISITOR
§INTERFACE PATTERNS§  – INTRODUZIONE ALLE INTERFACCE

Una interfaccia è una collezioni di metodi e variabili che rappresentano la parte visibile della classe che implementa l’interfaccia: in altra parola una interfaccia si può considerare come
*una dichiarazione di intenti*.

Una classe astratta senza metodi non abstract è simile ad una interfaccia, ma rimangono alcune differenze.
Differenze tra abstract classes e interfacce in Java:
– una classe può implementare più di una interfaccia ma non può estendere più di una classe abstract.
– una classe astratta può anche implementare metodi non astratti, mentre tutti i metodi di una interfaccia sono per forza astratti.
– una classe astratta può dichiarare e usare variabili di istanza, una interfaccia non può farlo, può solo creare constanti final e static.
– una classe astratta può avere diversi tipi di accesso ai metodi: public, protected, private o package (default). Tutti i metodi di una interfaccia sono implicitamente public.
– una classe astratta può definire costruttori, una interfaccia non può farlo.

Problema da risolvere e relativo pattern Interfaces:
– adattare l’interfaccia di una classe per corrispondere all’interfaccia che il cliente di aspetta: ADAPTER
– fornire una interfaccia semplice ad una collezioni di classi: FACADE
– definire una interfaccia che possa essere implementata sia da oggetti individuali sia da gruppi di oggetti: COMPOSITE
– disaccoppiare una astrazione dalla sua implementazione in modo che le due parti possano variare in modo indipendente: BRIDGE

SCJP Sun Certified Programmer for Java 6 Study Guide – Object Orientation

Object Orientation

Encapsulation (Exam Objective 5.1)

Il beneficio chiave dell’encapsulation è la possibilità di cambiare il codice di determinate classi, senza danneggiare altre classi che vi fanno riferimento.

Per ottenere questo beneficio è necessario nascondere i dettagli dell’implementazione dietro a una interfaccia pubblica. In questo caso, per interfaccia si intende un insieme di metodi accessibili dall’esterno, in pratica l’API del codice. Nascondendo i dettagli implementativi, si possono apportare modifiche sul codice senza forzare cambiamenti nel codice che lo chiama.
Un design che tiene conto dell’encapsulation permette di ottenere mantenibilità, flessibilità ed estensibilità.
Come implementare l’encapsulation:

  • mantenere le variabili di istanza private,
  • esporre metodi di accesso pubblici e forzare il codice chiamante a usare questi metodi invece delle di usare direttamente le variabili di istanza,
  • per i metodi, utilizzare la naming convention dei JavaBean (set<someProperty>, get<someProperty>).

Inheritance, Is-A, Has-A (Exam Objective 5.5)

Ogni classe Java è una sottoclasse della classe Object, quindi ogni classe, presente e futura, erediterà da Object.
Per l’esame è necessario sapere che si possono creare relazioni di ereditarietà estendendo una classe. E’ anche importante capire quali sono le due ragioni principali per usare l’ereditarietà:
1) promuovere il riuso del codice
2) usare il polimorfismo.

Riuso: un comune approccio di design è quello di creare classi base che espongano funzionalità comuni a un insieme di oggetti, per poi creare sottoclassi più specializzate che ereditino da essa. Il riuso del codice attraverso l’ereditarietà significa che metodi con funzionalità generiche non necessitano di essere re-implementati in più classi.

Polimorfismo: usando l’ereditarietà si può accedere alla classi in modo polimorfico, vale a dire che ogni sottoclasse può essere trattata come la classe padre.

IS-A and HAS-A Relationships
Per l’esame è necessario saper riconoscere se il codice implementa una relazione IS-A o una relazione HAS-A.

  • IS-A
    • Una relazione IS-A è un modo per dire “questa cosa è del tipo di questa altra cosa”, si può esprimere
      implementando l’ereditarietà fra classi (attraverso la parola chiave “extends”) o con l’implementazione di interfaccie (attraverso la parola chiave “implements”)
  • HAS-A
    • La relazione HAS-A è basata sull’uso, invece che sulla ereditarietà. In altre parole, la classe A HAS-A B se il codice nella classe A fa riferimento ad una istanza della classe B.

Polymorphism (Exam Objective 5.2)

Escludendo gli oggetti di tipo Object, tutti gli oggetti java sono polimorfici se passano il test della relazione IS-A per il loro stesso tipo e per la classe Object.

Da ricordare che l’unico modo per accedere ad un oggetto è attraverso reference variable, e ci sono dei concetti chiave da tenere a mente:

  • Una reference variable può essere solo di un tipo e, una volta dichiarato, questo tipo non può mai essere cambiato.
  • Una reference è una variabile, quindi può essere re-assegnata ad altri oggetti (a meno che non sia dichiarata final).
  • Il tipo della reference variable determina i metodi che possono essere invocati sull’oggetto a cui la variabile fa riferimento.
  • Una reference variable può rappresentare un oggetto dello stesso tipo del tipo dichiarato per la reference o ogni sottotipo del tipo dichiarato.
  • Il tipo dichiarato di una reference variable può essere una classe o una interfaccia. Se il tipo è un’interfaccia può indicare ogni oggetti di ogni classe che implementa tale interfaccia.

SCJP Sun Certified Programmer for Java 6 Study Guide – Declarations and Access Control

Identifiers & JavaBeans (Objectives 1.3 and 1.4)

1) Dichiarazioni, inizializzazioni, uso di primitive, arrays, enum e oggetti statici, 
di istanza e variabili locali. Usare identificatori legali (Legal Identifiers) per i nomi dellevariabili.
2) Dichiarazione di metodi sia statici che non statici, usare lo standard di naming dei 
JavaBean dove appropriato, dichiarazione e uso di liste di argomenti di lunghezza variabile
per i metodi.

Legal Identifiers: nomi accettati per le variabili. In generale devono essere composti da caratteri Unicode.

In particolare:

  • Iniziare con: una lettera/il carattere currency (“$”)/un carattere di connessione (per esempio “_”). Non possono iniziare con un numero.
  • Dopo il primo carattere, qualsiasi carattere Unicode, senza limiti di lunghezza.
  • Non deve essere uguale ad una parola chiave.
  • Sono case-sensitive.

Java Keywords

JavaBeans Standards

L’esame prevede di conoscere le regole di base per lo sviluppo di JavaBean.

Un JavaBean è una classe Java che:

  • ha delle proprietà: variabili di istanza private;
  • metodi pubblici per accedere alle proprietà: metodi setter per modificare il valore delle proprietà e metodi getter per recuperarne i valori;

JavaBean Naming Rules che è necessario conoscere:

  • Nomi dei metodi di accesso alle proprietà
    • proprietà non boolean:
      • getter: prefisso “get” + nome property con prima lettera maiuscola (per esempio per la property size il getter è getSize(). Non è obbligatorio avere una variabile privata “size”, getSize() rimane comunque un metodo JavaBean valido). Il metodo deve essere public, non prevedere argomenti  e avere come tipo di ritorno lo stesso tipo usato nel set della medesima proprietà.
      • setter: prefisso “set” + nome property con prima lettera maiuscola. Il metodo deve essere public, ritornare void e avere un argomento che rappresenta il tipo della proprietà.
    • proprietà boolean:
      • getter: il prefisso può essere “get” o “is”. Per il resto uguale alle proprietà non boolean.
      • setter: uguale alle proprietà non boolean

Dato che la specifica JavaBean supporta il modello ad eventi, è necessario anche conoscere lo standard di naming per la gestione dei listener.

JavaBean Listener Naming Rules che è necessario conoscere:

  • Metodi di registrazione di un listener: prefisso “add” + nome del tipo di listener (per esempio addActionListener() è un nome valido per un metodo che aggiunge un gestore di eventi Action).
  • Metodi di rimozione di un listener: prefisso “remove” + nome del tipo di listener.
  • Il tipo di listener da aggiungere/rimuovere deve essere passato come argomento dei metodi.
  • I metodi devono finire con la parola “Listener”.