Standardisiertes Event Handling zwischen Portlets
In unserem Beispiel ist eine Dokumentenliste zwischen den zwei verschiedenen Portlets auszutauschen. Hierzu stellt ebenfalls die JSR-286-Spezifikation eine passende Möglichkeit bereit: das Event Handling. Die Definition der Events erfolgt über QNames. In unserem Beispiel erfolgt zunächst die Definition in der XML-Datei portlet.xml:
<event-definition><qname xmlns:x="http:de.dmc.alfresco/events">x:DocumentList</qname><value-type>java.util.LinkedList</value-type></event-definition>
Nach der Definition gilt es zu bestimmen, welches Portlet ein solches Event senden und empfangen kann.
<portlet><portlet-name>AlfrescoSpaceBrowser</portlet-name>...<supported-publishing-event><qname xmlns:x="http:de.dmc.alfresco/events">x:DocumentList</qname></supported-publishing-event></portlet>...<portlet><portlet-name>AlfrescoDocumentBrowser</portlet-name>...<supported-processing-event><qname xmlns:x="http:de.dmc.alfresco/events">x:DocumentList</qname></supported-processing-event></portlet>
Die Nutzung von Events geht einher mit einem javax.portlet.ActionRequest. Dieser Request auf das Navigations-Portlet ist notwendig, um Informationen zwischen Portlets austauschen zu können. Ein JSF-Button oder JSF-Link bspw. generiert einen solchen ActionRequest. In diesem Beispiel implementieren wir eine Methode, die aufgerufen wird, sobald ein Benutzer ein Dokument im Portlet Repository Space Browser auswählt. Anschließend erfolgt das Auslesen der vorhandenen Dateien in diesem ausgewählten Space nach Listing 3. Über den ActionResponse-Mechanismus schicken wir die Liste auf die Reise. Portlets auf der aktuellen Seite (damit ist eine aggregierte Portlet-Seite gemeint), die dieses Event verarbeiten können (Listing 2), stellen das Ziel der Aufrufe von Liferay dar.
public void processNodeUUID(ActionEvent actionEvent){ActionResponse response = (ActionResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();ActionRequest request = (ActionRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();List<TreeDocument> files = this.fileFolderWebService .getDocumentsByParentFolderUUID(request.getParameter("nodeUUID"));AbstractTreeNode[] nodes = sortNodes(files);response.setEvent(new QName("http:de.dmc.alfresco/events", "DocumentList"), ( Serializable) Arrays.asList(nodes));}
Das Überschreiben der Methode javax.portlet.EventPortlet.processEvent ist eine zwingende Vorrausetzung für den Empfang und die Verarbeitung von Events. Der Aufruf dieser Methode erfolgt nach dem Aufruf von processAction() und vor der Verarbeitung der Render-Phase. Hierzu muss, wie schon in Listing 7 gezeigt, das GenericFacesPortlet im Portlet Resource Browser erweitert werden.
public void processEvent(EventRequest request, EventResponse response)throws PortletException, IOException {request.getPortletSession().setAttribute("documents", request.getEvent().getValue());}
Leider verfügen wir innerhalb der processEvent-Methode über keinen Zugriff auf einen validen FacesContext. Dieser wird sowohl vor als auch nach dem Aufruf dieser Methode neu aufgebaut. Aus diesem Grund muss das Ergebnis auf eine andere Weise zur späteren Verwendung zwischengespeichert werden. Die Nutzung der PortletSession zur direkten Ablage als Attribut oder in einer vorhandenen SessionBean ist hierfür am besten geeignet. Das Ablegen der Liste als Attribut des ActionRequests funktioniert dagegen nicht, da das aktuelle Portlet anschließend einen "neuen" RenderRequest aufbaut (das Portlet Document Browser löste selbst keinen ActionRequest aus).




