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.