L'uscita di Liferay DXP (e della sua controparte free Liferay 7) ha portato con sé numerose novità, prima fra tutte l'integrazione con OSGi. Tra i numerosi nuovi tool forniti allo sviluppatore ce n'è uno che mette a disposizione una shell per interagire con il container OSGi; sto parlando della Gogo shell (sottoprogetto di Apache Felix) accessibile con il comando telnet localhost 11311.

Una volta avuto accesso alla shell, possiamo vedere l'elenco di tutti i comandi disponibili semplicemente digitando help; ogni comando è costituito da uno scope (una sorta di raggruppamento) e da un nome.

Vediamo quindi come fare per creare un comando personalizzato da eseguire all'interno della Gogo shell.

Innanzitutto creiamo un progetto vuoto tramite Liferay IDE; a tale scopo il template api è minimale e va benissimo. Assicuriamoci quindi di avere le seguenti dipendenze all'interno del file build.gradle:

dependencies {
    compileOnly group: "com.liferay.portal", name: "com.liferay.portal.kernel", version: "2.0.0"
    compileOnly group: "javax.portlet", name: "portlet-api", version: "2.0"
    compileOnly group: "org.osgi", name: "org.osgi.service.component.annotations", version: "1.3.0"
}

Quello che vogliamo realizzare è un comando che visualizzi l'elenco delle company (se invocato senza parametri) oppure il dettaglio di una company (se invocato con il parametro companyId); creiamo quindi una classe Java con le opportune annotazioni OSGi:

package it.marconapolitano.liferay.gogo.command;

@Component(property = {
    "osgi.command.function=company", "osgi.command.scope=liferay"
}, service = Object.class)
public class CompanyCommand {
}

Come si può vedere le uniche proprietà OSGi da indicare sono il nome del comando (company) e lo scope da utilizzare (liferay). L'unica cosa fondamentale da ricordare è che il nome del comando deve essere uguale al nome dei metodi Java che implementeranno il comando stesso.

Andiamo quindi a definire il primo metodo ossia quello che, invocato senza parametri, visualizza l'elenco delle company:

package it.marconapolitano.liferay.gogo.command;

@Component(property = {
    "osgi.command.function=company", "osgi.command.scope=liferay"
}, service = Object.class)
public class CompanyCommand {

@Reference
private volatile CompanyLocalService _companyLocalService;

public void company() throws PortalException { List<Company> companies = _companyLocalService.getCompanies(); for (Company company : companies) { System.out.println(company.getPrimaryKey() + StringPool.COMMA_AND_SPACE + company.getName()); } } }

Tutto molto semplice: il metodo non accetta parametri, recupera l'elenco delle company e le visualizza a video. Aggiungiamo adesso l'altro metodo ossia quello che, invocato con il parametro companyId, visualizza il dettaglio della company:

package it.marconapolitano.liferay.gogo.command;

@Component(property = {
    "osgi.command.function=company", "osgi.command.scope=liferay"
}, service = Object.class)
public class CompanyCommand {

@Reference
private volatile CompanyLocalService _companyLocalService;

public void company() throws PortalException { List<Company> companies = _companyLocalService.getCompanies(); for (Company company : companies) { System.out.println(company.getPrimaryKey() + StringPool.COMMA_AND_SPACE + company.getName()); } }

public void company(long companyId) throws PortalException {
Company company = _companyLocalService.getCompany(companyId); System.out.println("companyId = " + company.getPrimaryKey()); System.out.println("name = " + company.getName()); System.out.println("active = " + company.isActive()); System.out.println("authType = " + company.getAuthType()); System.out.println("adminName = " + company.getAdminName()); System.out.println("emailAddress = " + company.getEmailAddress()); System.out.println("homeURL = " + company.getHomeURL()); System.out.println("maxUsers = " + company.getMaxUsers()); System.out.println("mx = " + company.getMx()); System.out.println("virtualHostname = " + company.getVirtualHostname()); System.out.println("webId = " + company.getWebId()); } }

Anche in questo caso nulla di particolare: il metodo accetta un parametro con cui viene recuperata la company e successivamente vengono visualizzati a video i dettagli.

Ora non resta che deployare il bundle e digitare il comando help nella Gogo shell; come per magia nell'elenco comparirà anche liferay:company. Per avere maggiori informazioni sul comando possiamo digitare help liferay:company e la shell ci indicherà la presenza dei 2 metodi, con e senza parametro. Non resta che provare a lanciare il nostro comando personalizzato con liferay:company oppure solamente company dal momento che non ci sono comandi omonimi in altri scope:

liferay:company
liferay:company 0
liferay:company 20116

Adesso serve solo un pò di fantasia per realizzare tutti i comandi di cui avete bisogno!