bloggers bloggers

Marco Napolitano
Messaggi: 79
Stelle: 0
Data: 17/02/22
Jader Jed Francia
Messaggi: 63
Stelle: 0
Data: 18/02/21
Paolo Gambetti
Messaggi: 2
Stelle: 0
Data: 11/11/19
Katia Pazzi
Messaggi: 1
Stelle: 0
Data: 27/06/19
Ezio Lombardi
Messaggi: 11
Stelle: 0
Data: 10/04/18
Chiara Mambretti
Messaggi: 25
Stelle: 0
Data: 27/02/17
Serena Traversi
Messaggi: 3
Stelle: 0
Data: 21/07/16
Francesco Falanga
Messaggi: 8
Stelle: 0
Data: 14/06/16
Antonio Musarra
Messaggi: 2
Stelle: 0
Data: 18/11/13
Simone Celli Marchi
Messaggi: 6
Stelle: 0
Data: 09/07/13
Indietro

Liferay e portlet cooperative Struts - annotation

Nell'articolo precedente (blog.d-vel.com/web/blog/home/-/blogs/liferay-e-portlet-cooperative-struts) abbiamo visto come utilizzare portlet cooperative Struts all'interno di Liferay 5.2.3 tramite la nuova piattaforma ad eventi.
Vediamo ora come rendere le cose ancora più eleganti attraverso l'utilizzo delle annotation.


Supponiamo di trovarci nella condizione in cui il sistema sia in grado di generare 3 o più eventi.
Come prima cosa avremo un censimento degli eventi simile al seguente:

<portlet-app>
<default-namespace>http://www.d-vel.com/events</default-namespace>
<event-definition>
<name>evento1</name>
<value-type>java.lang.Integer</value-type>
</event-definition>
<event-definition>
<name>evento2</name>
<value-type>java.lang.String</value-type>
</event-definition>
<event-definition>
<name>evento3</name>
<value-type>java.lang.Double</value-type>
</event-definition>
...
</portlet-app>


Supponiamo ora di avere una portlet in grado di processare ogni evento generato dal sistema. Il descrittore della portlet dovrà pertanto dichiarare tutti gli eventi utilizzabili, come di seguito riportato:

<portlet-app>
...
<portlet>
...
<supported-processing-event>
<name>evento1</name>
<name>evento2</name>
<name>evento3</name>
</supported-processing-event>
...
</portlet>
...
</portlet-app>


A questo punto ricordiamo che il portlet container, in caso di eventi pubblicati, invoca il metodo processEvent() di tutte le portlet registrate per quello specifico tipo di evento. Quindi la portlet (che dovrà processare tutti gli eventi) deve gestire la cosa nel modo seguente:

public void processEvent(EventRequest request, EventResponse response)
throws PortletException, IOException {
Event event = request.getEvent();

if (event.getName().equals("evento1")) {
Integer value = (Integer) event.getValue();
...
}
if (event.getName().equals("evento2")) {
String value = (String) event.getValue();
...
}
if (event.getName().equals("evento3")) {
Double value = (Double) event.getValue();
...
}
...
}


Per forza di cose è necessario definire una catena di blocchi if per intercettare tutti i vari tipi di eventi e questo rende il codice del metodo più pesante e difficile da leggere. Questo problema si risolve però elegantemente utilizzando le annotation.
Innanzitutto va eliminato dalla portlet il metodo processEvent(); dopodichè va definito un metodo per ogni tipo di evento da gestire, con la medesima firma del processEvent():

public void <nomeMetodo>(EventRequest request, EventResponse response)
throws PortletException, IOException;

Infine, ciascuno di questi metodi deve essere annotato con @ProcessEvent al fine di comunicare al container quale tipo di evento gestisce:

@ProcessEvent(name = "evento1")
public void processEvent1(EventRequest request, EventResponse response)
throws PortletException, IOException {
Event event = request.getEvent();
Integer value = (Integer) event.getValue();
...
}

@ProcessEvent(name = "evento2")
public void processEvent2(EventRequest request, EventResponse response)
throws PortletException, IOException {
Event event = request.getEvent();
String value = (String) event.getValue();
...
}

@ProcessEvent(name = "evento3")
public void processEvent3(EventRequest request, EventResponse response)
throws PortletException, IOException {
Event event = request.getEvent();
Double value = (Double) event.getValue();
...
}


Come si può notare, la soluzione è ora molto più pulita ed elegante: la catena di if è stata sostituita dai vari metodi e soprattutto non è più necessario verificare il tipo di evento, dal momento che ogni singolo metodo viene invocato a seguito dello specifico evento per cui è stato annotato.

Precedente
Commenti
Aggiungi Commento
Jader Jed Francia
Se siete "allergici" alle annotation emoticon, anche se devo ammettere che questa notazione è in effetti elegante, si _deve_ ovviare al problema del blocco degli if attraverso una factory, ad esempio:

public void processEvent(EventRequest request, EventResponse response)
throws PortletException, IOException {
Event event = request.getEvent();
EventProcessor processor = EventProcessorFactory.getProcessor(event.getName());
processor.process(event);
...
}

Lascio ad ognuno di voi immaginare l'interfaccia EventProcessor e la factory EventProcessorFactory.. emoticon

I vantaggi di questo approccio sono anche quelli di fattorizzare in una classe esterna al portlet le logiche di processing -che diventano quindi riusabili- all'interno del software, migliorando la modularizzazione del codice e il riuso degli oggetti.
Inviato il 09/07/15 14.03.