sabato 6 novembre 2010

Personalizzare la Dashboard in Jboss Portal

0 commenti

In Jboss-Portal gli utenti una volta effettuato il login hanno a disposizione la dashboard, una sezione personale del utente che può organizzare a suo piacere. La dashboard viene creata al primo login del utente usando come base il portale /template. Ma se noi volessimo avere più template per la creazione della dashboard? Avere dei template diversi in modo da creare diverse tipologie di dashboard in base al utente? Per esempio se un utente del portale è amministratore possiamo avere un template già configurato con tutte le portlet relative all'amministrazione del portale, così come per un redattore un configurazione che contiene strumenti redazionali o per un semplice utente una configurazione che contiene il suo profilo e varie utilità del portale.
In Jboss-Portal questa funzionalita non è possibile e per introdurla dobbiamo agire sul MBean CustomizationManager. Questo servizio si occupa della creazione di recuperare la dashboard dell'utente e se ancora non esiste la crea. Oltre alla dashboard gestisce anche il recupero delle istanze delle portlet che compongono le pagine del portale.
Come prima cosa creiamo un progetto jar chiamandolo jboss-mbean-extensions si può fare anche usando maven con il commando



mvn archetype:generate -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.1 -DgroupId=it.ruletheobject -DartifactId=jboss-mbean-extensions

modifichiamo il pom.xml aggiungendo le seguneti dipendenze alle librerie del Jboss necessarie.
<dependency>
<groupId>jboss</groupId>
<artifactId>jboss-system</artifactId>
<version>4.0.2</version>
</dependency>
<dependency>
<groupId>jboss.common</groupId>
<artifactId>jboss-common</artifactId>
<version>1.2.1.GA-brew</version>
</dependency>
<dependency>
<groupId>org.jboss.portal.core</groupId>
<artifactId>jems</artifactId>
<version>2.7.1.GA</version>
</dependency>
<dependency>
<groupId>org.jboss.portal.core</groupId>
<artifactId>security</artifactId>
<version>2.7.1.GA</version>
</dependency>
<dependency>
<groupId>org.jboss.portal.identity</groupId>
<artifactId>identity-identity</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>org.jboss.portal.core</groupId>
<artifactId>core</artifactId>
<version>2.7.1.GA</version>
</dependency>

<dependency>
<groupId>jboss</groupId>
<artifactId>jboss-jmx</artifactId>
<version>4.2.3.GA</version>
</dependency>



Per creare il nostro servizio MyCustomizationManagerService dobbiamo estendere AbstractJBossService e implementare l'interfaccia CustomizationManager che espone i seguenti metodi

CustomizationManager.java

Instance getInstance(Window window) throws IllegalArgumentException;

Instance getInstance(Window window, User user) throws IllegalArgumentException;

Portal getDashboard(User user) throws IllegalArgumentException;

boolean isDashboard(PortalObject object, User user);

void destroyDashboard(String userId);

Il metodo che ci interessa è getDashboard(User user) gli atri metodi possiamo implementarli basandoci CustomizationManagerService di jboss.
Oltre a implementare i metodi del interfaccia dobbiamo aggiungere gli attributi di classe che verrano iniettati dal jboss-service.xml
private String dashboardContextId;
private InstanceContainer instanceContainer;
private PortalAuthorizationManagerFactory portalAuthorizationManagerFactory;
private PortalObjectContainer portalObjectContainer;
private UserModule userModule;
private RoleModule roleModule;


Il metodo getDashboard(User user) e il metodo che recupera la dashbord del utente qui dobbiamo inserire la nostra logica di selezione del template in base alla tipologia del utente che ha effettuato il login.

public Portal getDashboard(User user) throws IllegalArgumentException {
//
Portal dashboardPortal = null;
if (user != null) {
String userId = getUserId(user);
try {
Context dashboardContext = portalObjectContainer
.getContext(dashboardContextId);
//
dashboardPortal = dashboardContext.getPortal(userId);
// Creare la dashboard se non esiste
if (dashboardPortal == null) {
String userTemplate = getUserTemplate(userId);
Portal templatePortal = null;
PortalObjectId template;
if (userTemplate != null) {
template = PortalObjectId.parse("/" + userTemplate,
PortalObjectPath.CANONICAL_FORMAT);
templatePortal = (Portal) portalObjectContainer.getObject(template);
}

if (templatePortal == null) {
template = PortalObjectId.parse("/template",
PortalObjectPath.CANONICAL_FORMAT);
templatePortal = (Portal) portalObjectContainer.getObject(template);
}

// Copy the template portal
dashboardPortal = (Portal) templatePortal.copy(dashboardContext, userId, false);
copy(templatePortal, dashboardContext.getChild(userId));

}
}
catch (DuplicatePortalObjectException e) {
log.error("", e);
}
}
return dashboardPortal;
}



La dashboard dell'utente viene creata al primo login. infatti nel metodo getDashboard prima si va a controllare se l'utente ha una dashboard e in caso contrario si procede nella creazione.Per prima cosa dobbiamo fare un collegamento tra utente e il template da usare. Per il nostro esempio ho usato una convenzione basata sui ruoli del utente. Se il ruolo del utente e admin uso il template "/template_admin" altrimenti "/template_user". Potete decidere la relazione tra utente e template secondo le vostre neccessita per esempio salvandolo nel database , un file di properties , una property del utente sul ldap etc.


private String getUserTemplate(User user) {
String template = "template_user";
try {

final Set roles = membershipModule.getRoles(user);
for (Role role:roles){
if(role.getName().equals("Admin")){
template="template_admin";
}
}
} catch (IdentityException e) {
e.printStackTrace();
}

return template;
}



Una volta recuperato il template da usare procediamo a recuperare il portale corrispondente e procedere alla copia e assiociandolo come dashboard del utente.

PortalObjectId template = PortalObjectId.parse("/" + userTemplate,    
portalObjectPath.CANONICAL_FORMAT);
Portal templatePortal = (Portal) portalObjectContainer.getObject(template);
(Portal) templatePortal.copy(dashboardContext, userId, false);
copy(templatePortal, dashboardContext.getChild(userId));


Per vedere in opera il nostro CustomizationManager dobbiamo configurare il jboss-service.xml presente nella cartella jboss-portal.sar/META-INF trovare la configurazione del Customization manager e sostituire la configurazione di org.jboss.portal.core.impl.model.CustomizationManagerService con la nostra
it.ruletheobject.jboss.core.customization.MyCustomizationManagerService.

<!-- Customization manager -->
<mbean code="it.ruletheobject.jboss.core.customization.MyCustomizationManagerService"
name="portal:service=CustomizationManager"
xmbean-dd="" xmbean-code="org.jboss.portal.jems.as.system.JBossServiceModelMBean">
<xmbean/>
<depends optional-attribute-name="PortalAuthorizationManagerFactory" 
proxy-type="attribute">
portal:service=PortalAuthorizationManagerFactory
</depends>
<depends optional-attribute-name="InstanceContainer" 
proxy-type="attribute">portal:container=Instance</depends>
<depends optional-attribute-name="PortalObjectContainer" 
proxy-type="attribute">portal:container=PortalObject
</depends>
<depends>portal:service=Module,type=IdentityServiceController</depends>
<attribute name="DashboardContextId">dashboard</attribute>
</mbean>


Dopo aver configurato il nostro Mbean facciamo il build del nostro progetto con mvn clean install e copiare il jar creato sotto la cartella target sotto jboss-portal.sar/lib.
Dopo aver avviato il portale bisogna creare i portali che verrano usati come template in questo caso /template_user e /template_admin.
Per testare il funzionamento corretto creiamo due utenti uno amministratore e uno user e effettunado il login controlliamo se sono stati usati i corretti template per creare la dashboard.

La versione di jboss portal testata è la 2.7.2