Using Plugins to Extend and
Customize Liferay
R&D Engineer, SMC Treviso
Andrea Di Giorgi
Portlet JSR-286
Punti di Estensione
Utilizzo API pubbliche
Modifica implementazioni classi (Spring e properties)
Modifica pagine JSP
Utilizzo API private
Modifica codice sorgente
Plugins
portlets
themes
layouttpls
hooks
ext
webs
Modifica properties (alcune)
Modifica traduzioni
Aggiunta e modifica pagine JSP
Nuovi Indexer Post Processor
Nuove implementazioni servizi generati via Service Builder
Nuovi Servlet Filter
Modifica Action Struts
hooks
Portlet + Hook per ModelListener, integrazioni
nei portlet core di Liferay, ecc.
Modifica properties non supportate dagli hook
Nuove implementazioni per i bean dichiarati tramite Spring o
properties
Modifica impostazioni dei portlet standard Liferay
liferay-portlet.xml e portlet-custom.xml
Nuove taglib e servizi di utilità
Sovrascrittura diretta di classi
ext
Modulari
Hot deployment
Hot undeployment
Modifiche reversibili
hooks
Massima personalizzazione
Il deployment richiede il
riavvio del portale e il
redeploy degli altri plugin
Undeployment «difficoltoso»
Ridotta manutenibilità
ext
Hook ove possibile
Estendere/includere, non sovrascrivere
Un solo plugin ext
Non sovrascrivere classi
Plugins Architecture
Ambiente di sviluppo per i plugin Liferay
Basato su Apache Ant
Richiede un bundle Liferay locale
Supporto per Maven in fase di sviluppo
Plugins SDK
Un Plugins SDK per ciascun progetto «portale»
Versionare l’intero Plugins SDK
1 directory del Plugins SDKin /portlets, /hooks, ecc.
1 progetto Eclipse/Liferay IDE
1 plugin Liferay
1 file .war
1 webapp
Plugin Deployment
/deploy
AutoDeployScanner
/webapps
PluginContextListener
HookHotDeployListener
PortletHotDeployListener
ThemeHotDeployListener
…
HookAutoDeployListener
PortletAutoDeployListener
ThemeAutoDeployListener
…
Class Loading
Portal Impl Plugin A Plugin B
App Server Classloader(s)
JDK Classloader(s)
portal-service.jar
util-bridges.jarutil-java.jarutil-taglib.jar
Class Loading
Tutto il codice eseguito nel contesto del plugin
Classi Java eseguite nel contesto del plugin
Pagine JSP eseguite nel contesto del portale
Tutto il codice eseguito nel contesto del portale
PortalClassInvoker
Invocare un metodo di una classe del portale da un plugin
PortletActionInvoker
Invocare una Action Struts del portale da un plugin
PortletClassInvoker
Invocare un metodo di una classe di un plugin da un altro
plugin
Class Loading
Esempi
Codice eseguito nel contesto del plugin
Basic Authentication
Controllo dei permessi basato sul PermissionChecker
Definizione in web.xml
servlet
SecureFilter
ServletAuthorizingFilter
Servlet
http://issues.liferay.com/browse/LEP-4682
Contenuto di un file della Document Library dato il suo
fileEntryId
Basic Authentication
Controllo del permesso di visualizzazione
Esempio
http://localhost:8080/authenticated-servlet-hook/file_entry/42
<filter><filter-name>Secure Filter</filter-name><filter-class>com.liferay.portal.kernel.servlet.PortalClassLoaderFilter
</filter-class><init-param><param-name>filter-class</param-name><param-value>com.liferay.portal.servlet.filters.secure.SecureFilter
</param-value></init-param><init-param><param-name>basic_auth</param-name><param-value>true</param-value>
</init-param></filter>
web.xml
<filter><filter-name>Servlet Authorizing Filter</filter-name><filter-class>com.liferay.portal.kernel.servlet.PortalClassLoaderFilter
</filter-class><init-param><param-name>filter-class</param-name><param-value>com.liferay.portal.servlet.filters.servletauthorizing.ServletAuthorizingFilter
</param-value></init-param>
</filter>
<filter-mapping><filter-name>Secure Filter</filter-name><url-pattern>/file_entry/*</url-pattern>
</filter-mapping><filter-mapping><filter-name>Servlet Authorizing Filter</filter-name><url-pattern>/file_entry/*</url-pattern>
</filter-mapping>
web.xml
<servlet><servlet-name>File Entry Servlet</servlet-name><servlet-class>com.sympo.servlet.FileEntryServlet</servlet-class>
</servlet><servlet-mapping><servlet-name>File Entry Servlet</servlet-name><url-pattern>/file_entry/*</url-pattern>
</servlet-mapping>
web.xml
Servizi remoti di un plugin esposti come Web Service JSON
Basic/Digest Authentication
Controllo dei permessi basato sul PermissionChecker
Deserializzazione automatica degli argomenti
long, String, boolean, Date, Locale, List, Map, etc.
Loose Serialization del valore di ritorno
Model, List, Map, @JSON, JSONSerializable
JSON Web Service
http://www.liferay.com/community/wiki/-/wiki/Main/JSON+Serialization
http://www.liferay.com/documentation/liferay-portal/6.1/development/-/ai/json-web-services
Numero di file nella Document Library suddivisi per «tipo»
(immagine, pdf, ecc.) e ultimo file modificato per ciascun tipo
Basic Authentication
Dati filtrati in base ai permessi dell’utente
Esempio
http://localhost:8080/api/secure/jsonws/json-web-service-
hook.dlstatistics/get-group-statistics?groupId=10180
http://issues.liferay.com/browse/LPS-27014
<servlet><servlet-name>JSON Web Service Servlet</servlet-name><servlet-class>com.liferay.portal.kernel.servlet.PortalClassLoaderServlet
</servlet-class><init-param><param-name>servlet-class</param-name><param-value>com.liferay.portal.jsonwebservice.JSONWebServiceServlet
</param-value></init-param><load-on-startup>0</load-on-startup>
</servlet><servlet-mapping><servlet-name>JSON Web Service Servlet</servlet-name><url-pattern>/api/jsonws/*</url-pattern>
</servlet-mapping><servlet-mapping><servlet-name>JSON Web Service Servlet</servlet-name><url-pattern>/api/secure/jsonws/*</url-pattern>
</servlet-mapping>
web.xml
Elaborazioni eseguite in modo asincrono al caricamento di un
file nella Document Library
Implementazioni dell’interfaccia
com.liferay.portlet.documentlibrary.util.DLProcessor
Proprietà dl.file.entry.processors
DLProcessor
Libreria esterna per leggere i dati Exif delle immagini
Latitudine e longitudine come Custom Field
Coordinate in una mappa nel portlet Document Library
Esempio
https://github.com/sergiogonzalez/image-geolocation-hook
hook
<hook><portal-properties>portal.properties</portal-properties><custom-jsp-dir>/custom_jsps</custom-jsp-dir>
</hook>
application.startup.events=com.sympo.geolocation.AddImageGeoFieldsActiondl.file.entry.processors=com.sympo.geolocation.ImageGeoLocationImpl
liferay-hook.xml
portal.properties
«Disinfetta» i contenuti aggiunti dagli utenti
Commenti, blog, message board, wiki, calendario, ecc.
Eseguito prima del salvataggio nel database
Può modificare e adattare il contenuto
Sanitizer
portlet-model-hints.xml
<field name="title" type="String"><sanitize content-type="text/plain" modes="ALL" />
</field>
Meccanismo per menzionare un utente del portale
@screename in un commento
Invio mail di notifica all’utente menzionato
Esempio
https://github.com/sergiogonzalez/mention-notifications-hook
hook
<hook><portal-properties>portal.properties</portal-properties><custom-jsp-dir>/custom_jsps</custom-jsp-dir><service><service-type>com.liferay.portlet.messageboards.service.MBMessageLocalService
</service-type><service-impl>com.sympo.portlet.messageboards.service.MentionUsersMessageServiceImpl
</service-impl></service>
</hook>
application.startup.events=com.sympo.action.AddMentionedUsersFieldsActionsanitizer.impl=com.sympo.sanitizer.MentionSanitizerImpl
liferay-hook.xml
portal.properties
Ottenere un utente da una request non autenticata
Cookie, Header, sessione, ecc.
Integrazioni con sistemi SSO
Implementazioni dell’interfaccia
com.liferay.portal.security.auth.AutoLogin
Proprietà auto.login.hooks
AutoLogin
https://github.com/sergiogonzalez/twitter-login-hook
Controllo file nella Document Library
Implementazione dell’interfaccia
com.liferay.portlet.documentlibrary.antivirus.AntivirusScanner
Proprietà dl.store.antivirus.impl
Antivirus
https://github.com/sergiogonzalez/eset-antivirus-hook
Grazie!
Top Related