jAPS2.0 - Plugin Pattern

Do It The jAPS Way

Eugenio Santoboni

Prima e Completa Versione in Italiano 
Chief Solution Engineer
AgileTec s.r.l.

Legal Notice

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the Appendix entitled "GNU Free Documentation License".

The copyright holders make no representation about the suitability of this Document for any purpose. It is provided “as is” without expressed or implied warranty. If you modify this Document in any way, identify your resulting Document as a variant of this Document.

2010-03-25

Revision History
Revision 1.22010-03-19MEM

Aggiornamento del paragrafo Directory: src del capitolo Struttura del package con aggiunta dei file global-messages_XY.properties Revisione per il rilascio della versione 2.0.10

Revision 1.12009-10-29ES

Aggiornamento del paragrafo i18n del capitolo Naming convention

Revision 1.02009-07-27ES

Prima Versione Pubblica

Abstract

Questo documento descrive le caratteristiche, la struttura e i componenti di un plug-in jAPS. Esso fornisce inoltre le linee guida che devono essere seguite dagli sviluppatori Java per la realizzazione di nuovi plugin per jAPS 2.0.


Chapter 1. Scopo del documento

Introduzione

Lo scopo di questo documento è quello di fornire una descrizione completa della struttura del jAPS-Plugin e le linee guida che consentano di sviluppare e predisporre un nuovo Plugin su base jAPS 2.0.

A chi è destinato

Questo documento è destinato agli sviluppatori che intendono creare un nuovo Plugin su jAPS 2.0.

Prerequisiti

Per poter utilizzare efficacemente le informazioni contenute in questo documento, è necessario avere competenze di base su: piattaforma Java, strumenti di sviluppo Eclipse, servlet engine Apache Tomcat, database PostgreSQL.

Riferimenti

Ulteriori informazioni possono essere richieste scrivendo alle mailing-list:

È inoltre possibile consultare la documentazione presente in:

jAPS 2.0 Project - Sito per gli sviluppatori

Chapter 2. Cosa è jAPS-Plugin

Il jAPS-Plugin è un modulo che consente di aggiungere nuove funzionalità al framework jAPS 2.0 o di evolverne alcune esistenti.

Il jAPS-Plugin rappresenta ciò che viene comunemente individuato come Servizio Applicativo, per cui i principi che guidano la costruzione di un Plugin sono sostanzialmente gli stessi che ne guidano la sua implementazione secondo il documento jAPS2.0 - Pattern di Integrazione Servizi Applicativi di jAPS.

I Plugin si possono classificare in due tipi fondamentali:

  • PurePlugins (o Plugin propriamente detti)

  • Modifications

I PurePlugin forniscono nuove funzionalità a jAPS 2.0 senza però alterare le funzionalità già esistenti.

I PurePlugin rappresentano i plugin ideali in quanto hanno un impatto nullo sulle funzionalità preesistenti, e la presenza simultanea di più PurePlugin in una singola installazione di jAPS 2.0 non causa problemi di incompatibilità reciproca in quanto ogni modulo lavora in maniera completamente indipendente l'uno dall'altro.

I Plugin di tipo Modification sono invece quelli che integrano, sostituiscono, o modificano il comportamento di elementi del Core di jAPS 2.0.

A causa della loro natura invasiva sul sistema, possono avere particolari procedure di installazione e necessitare di particolare attenzione in presenza di altri Plugin (siano essi di tipo PurePlugin o di tipo Modification) per gestire al meglio la possibilità di sovrapposizioni e conflitti.

Proprio per ridurre al minimo il pericolo di sovrapposizioni e conflitti, lo sviluppo di ogni Modification deve essere condotta in maniera tale da limitare al minimo gli elementi che agiscono sul Core; questo fondamentale obiettivo può essere raggiunto sfruttando al meglio gli elementi messi a disposizione dal sistema e dai framework componenti (come Spring e Struts2), come per esempio il servizio di Notifica Eventi, l'AOP, l'architettura ad Interceptors nativa di Struts2, e molti altri.

Chapter 3. Struttura del package

Struttura del package

Ogni Plugin (sia PurePlugin che Modification) è rilasciato in un package composto da 3 elementi fondamentali:

  1. Documento: Readme
  2. Directory: src
  3. Directory: doc

La struttura delle Directory di un Plugin

La struttura delle Directory è simile allo Standard Directory Layout from the Apache Maven Project.

Example 3.1. The Directory Layout of a typical Plugin (continua)

wiz@id:~/jAPS2-Plugin-jpuserprofile-1.0$ tree -dx
.
|-- doc
|   `-- jAPS2.0-Plugin_UserProfile
|       |-- fo
|       |   `-- img
|       |-- html
|       |   |-- css
|       |   `-- img
|       |-- pdf
|       `-- ps
				

Example 3.2. (dalla pagina precedente) Struttura Directory di un Plugin tipico

|
`-- src
    |-- java
    |   |-- main
    |   |   `-- com
    |   |       `-- agiletec
    |   |           `-- plugins
    |   |               `-- jpuserprofile
    |   |                   |-- aps
    |   |                   |   |-- externalframework
    |   |                   |   |   `-- common
    |   |                   |   `-- system
    |   |                   |       `-- services
    |   |                   |           `-- profile
    |   |                   |               `-- model
    |   |                   `-- apsadmin
    |   |                       |-- common
    |   |                       |   `-- attribute
    |   |                       |       `-- action
    |   |                       |           `-- list
    |   |                       `-- user
    |   `-- test
    |       `-- test
    |           `-- com
    |               `-- agiletec
    |                   `-- plugins
    |                       `-- jpuserprofile
    |                           |-- aps
    |                           |   |-- externalframework
    |                           |   |   `-- common
    |                           |   `-- system
    |                           |       `-- services
    |                           `-- apsadmin
    |                               `-- common
    |-- sql
    `-- webapp
        |-- WEB-INF
        |   |-- lib
        |   `-- plugins
        |       `-- jpuserprofile
        |           |-- aps
        |           |   `-- jsp
        |           |       `-- externalFramework
        |           |-- apsadmin
        |           |   |-- conf
        |           |   `-- jsp
        |           |       `-- common
        |           |           `-- template
        |           |               `-- extraresources
        |           `-- conf
        |               `-- managers
        `-- resources
            `-- plugins
                `-- jpuserprofile

62 directories
				

Documento: Readme

Il Readme è un breve documento (massimo 40 righe per 80 colonne) nel quale vengono spiegate le funzionalità del Plugin e la versione di jAPS per la quale il Plugin è stato sviluppato e testato. Il documento ha lo scopo di fornire una immediata visione sul Plugin.

Directory: src

La directory contiene tutte le componenti necessarie per poter integrare il Plugin in un progetto basato su jAPS 2.0 ed impiantato su Eclipse IDE (dalla versione 3.4 Ganymede).

La directory contiene:

Sorgenti Java

I file sono posizionati dentro la subdirectory java/main.

Le classi Java del Plugin devono essere scritte secondo lo standard di codifica del framework jAPS 2.0. Inoltre esse devono essere raccolte dentro il package <DOMINIO_R>.plugins.<PLUGIN_ID> dove <DOMINIO_R> è l'inverso del nome di dominio del soggetto (azienda, associazione, sito web, persona fisica...) che sviluppa il plugin.

Example 3.3. Dal nome dominio al nome del Package

Company: MyCompany.com, package: com.mycompany.*


Per ciascuna classe deve essere compilato il javadoc in lingua inglese per consentire l'immediata lettura del codice e la comprensione del flusso applicativo. Ogni interfaccia e classe concreta deve presentare il javadoc in testata, in ogni metodo e variabile pubblica o privata (consigliato anche nei metodi privati complessi o poco leggibili).

Nel caso in cui il Plugin presenti un'interfaccia di amministrazione di jAPS 2.0, nella root delle sorgenti java deve essere presente un file <PLUGIN_ID>-japs-struts-plugin.xml che contenga il richiamo ai file di configurazione delle azioni esposte.

La directory ...<CODICE_PLUGIN/src continene le directories aps e apsadmin. In apsadmin si travano sempre i file global-messages_<LOCALE_CODE>.properties: questi file contengono le label delle voci di menu e di eventuali interfacce globali.

Important

I file di property devono sempre contenere almeno queste due voci:

  • <CODICE_PLUGIN.code=<CODICE_PLUGIN>

  • <CODICE_PLUGIN>.name=<descrizione plugin>

Le librerie

Le librerie sono posizionate nella subdirectory webapp/WEB-INF/lib.

La directory contiene la specifica libreria del Plugin, di nome jAPSPlugin-<PLUGIN_ID>-<VERSIONE>.jar e l'insieme delle librerie aggiuntive necessarie e non comprese nella distribuzione base del framework jAPS 2.0.

I test junit

I test junit sono posizionati nella subdirectory java/test.

Ogni funzionalità del Plugin deve essere accompagnata da un corrispondente set di unit test; le classi di test devono trovarsi dentro un package test.<DOMINIO_R>.plugins.<PLUGIN_ID>.

L'ambiente di test deve essere strutturato in modo tale che in fase di inizializzazione carichi tutto il contesto del Core di jAPS 2.0 e tutti i Bean del singolo Plugin (più eventualmente quelli necessari al suo utilizzo).

I file jsp e la configurazione

I file sono posizionati nella subdirectory webapp/WEB-INF/plugins/<PLUGIN_ID>.

Tale directory deve avere lo stesso nome del codice del plugin e deve essere posizionata all'interno della directory /WEB-INF/plugins/.

La directory deve contenere le subdirectory aps, apsadmin, conf. La struttura di queste subdirectory ricalca perfettamente la struttura delle corrispondenti subdirectory posizionate all'interno della directory WEB-INF del Core di jAPS 2.0.

La subdirectory aps contiene i file di cui ha bisogno il Front-End del Plugin.

La directory contiene:

  • La subdirectory jsp/showlets, per ogni Showlet fornita con il Plugin.
  • La subdirectory jsp/models, per ogni Page Model fornito con il Plugin.
  • La subdirectory jsp/externalFramework (opzionale), per i file jsp utilizzata per la Showlet speciale External Framework.
  • La subdirectory tld, per la definizione di ogni custom tag utilizzato nell'area di Front-End.

    Example 3.4. Il nome appropriato per il file tld

    <PLUGIN_ID>-aps-core.tld


La subdirectory apsadmin contiene i file di cui ha bisogno il Back-End del Plugin.

La directory contiene:

  • La subdirectory jsp, con una subdrectory per ogni componente e tutti i file jsp di cui ha bisogno ogni interfaccia utente.
  • La subdirectory conf, con una subdrectory per ogni componente e tutti i file di configurazione di ogni classe Action (Spring Beans) e la configurazione dei Tiles.

    Example 3.5. La codifica obbligatoria del nome per il file dei Tiles

    <PLUGIN_ID>-tiles.xml


  • La subdirectory tld, per la definizione di ogni custom tag utilizzato nell'area di Back-End.

    Example 3.6. Il nome appropriato per il file tld per l'area di amministrazione.

    <PLUGIN_ID>-apsadmin-core.tld


la subdirectory conf contiene la configurazione dei file di configurazione di tutti i bean (Spring Object) used by the Plugin nel Front-End (definizione dei Manager e degli ementi a supporto delle showlet).

Nel caso in cui il Plugin necessiti della predisposizione di nuovi DataSource o della specifica di percorsi di file o cartella su disco (o in generale di configurazioni di Tipo Sistemistico), nella cartella devono essere posizionati due file (corrispondenti a quelli presenti nella distribuzione base di jAPS 2.0):

  • systemParams.properties: file di property contenente tutti gli elementi di configurazione.
  • systemConfig.xml: file di configurazione base di Spring del Plugin nel quale deve essere posizionato il property-placeholder necessario per l'utilizzo delle property definite (nel file di property descritto precedentemente) e la definizione dei Bean DataSource (Spring Object) propri del Plugin (i cui parametri di configurazione vengono riferiti alle property definite).

La subdirectory opzionale extras contiene risorse o subdirectories che non trovano naturale collocazione nelle directory descritte precedentemente.

Le necessarie risorse statiche (CSS, immagini, Javascript...)

I file sono posizionati dentro la directory webapp/resources/plugins/<PLUGIN_ID>.

La cartella deve presentare le subdirectory necessarie al Plugin, rispettando la naming convention e organizzazione della directory resources della distribuzione base di jAPS 2.0: administration e static con le loro subdirectories.

Example 3.7. Alcune corrette subdirectories

static/css, static/img, administration/js


Example 3.8. Plugin jpuserprofile: path corretto per i CSS del frontend pubblico

/resources/plugins/jpuserprofile/static/css/


Directory: doc

La directory contiene la documentazione a corredo del Plugin.

La directory deve contenere un documento con le specifiche tecniche e funzionali, redatto preferibilmente in lingua inglese, con le seguenti informazioni:

  • La descrizione completa delle funzionalità del Plugin.
  • L'indicazione della versione del Plugin e della versione di jAPS 2.0 (Es: 2.0 oppure > 2.0.2 oppure >= 2.0 o altro) con la quale il Plugin è dichiarato compatibile e funzionante, e delle eventuali dipendenze da altri jAPS-Plugin (con indicate le versioni).
  • Le istruzioni dettagliate per l'installazione in istanze di jAPS già in produzione, eventualmente accompagnate dagli script sql necessari.
  • Le istruzioni dettagliate per l'installazione del Plugin negli Ambienti di Sviluppo basate Eclipse IDE versione 3.4 Ganymede (o superiore). Devono essere comprese le istruzioni per configurare correttamente i junit test.
  • L'indicazione del tipo del Plugin (se PurePlugin or Modification). Nel caso in cui si tratti di Modification, devono essere indicate dettagliatamente le funzionalità del Core di jAPS 2.0 che sono state oggetto di modifica; devono essere inoltre indicati tutti i Bean (Spring Object) sovrascritti dalla Modification e le interfacce utente sostituite e/o modificate.

Chapter 4. Naming convention

Naming convention

Di seguito la naming convention da adottare durante lo sviluppo di un plugin.

Id e nome

L'id del Plugin è l'indicativo univoco del Plugin; deve contenere il prefisso jp, deve essere scritto tutto in minuscolo e contenere solo caratteri alfabetici (non numeri, caratteri speciali o spazi).

L'id è diverso dal nome poichè il nome consente l'utilizzo del carattere spazio e di caratteri speciali.

Example 4.1. Nome ed Id del Plugin

User Profile è il nome del jAPSPlugin di id jpuserprofile.


Sorgenti

Le classi Java del Plugin devono essere scritte seguendo lo standard di Codifica di jAPS 2.0 framework. Le sorgenti devono essere incluse completamente dentro il package <DOMINIO_R>.plugins.<PLUGIN_ID> dove <DOMINIO_R> è l'inverso del nome di dominio del soggetto (azienda, associazione, sito web, persona fisica...) che sviluppa il plugin.

Example 4.2. Dal nome dominio al nome del package

Company: MyCompany.com, package: com.mycompany.plugins.<PLUGIN_ID>


Example 4.3. Dal nome dominio al nome del package

Company: MyCompany.com, package: test.com.mycompany.plugins.<PLUGIN_ID>


La sintassi richiama quelle definite dallo Standard [Java Language Specification di Sun Microsystems].

Nome del jar

Il nome della libreria jar deve essere: jAPSPlugin-<PLUGIN_ID>-<VERSION>.jar.

Directory sotto WEB-INF/plugins

Il nome della directory del Plugin che contiene tutte le jsp ed i file di configurazione deve essere uguale al codice del Plugin WEB-INF/plugins/<PLUGIN_ID>.

Risorse statiche

Guarda il capitolo precedente.

Nomi Beans (Spring Objects) del core del Plugin

Per evitare sovrapposizioni con nomi utilizzati nel core o da altri Plugin, tutti i nomi (id) dei bean devono presentare come prefisso l'id del Plugin (comprensivo del "jp" iniziale). Nel caso di jAPSManager, il nome (id) del Manager deve essere <PLUGIN_ID><SERVICE_NAME>Manager.

Nel caso in cui il jAPSPlugin sovrascriva un Bean del Core (o un Bean di un Plugin inserito come dipendenza), il nome (id) deve corrispondere a quello che si sostituisce. Tale operazione deve essere descritta precisamente nella documentazione tecnica.

Beans (Spring Objects) delle Azioni (Struts2 Objects)

Gli identificativi di tutti i Bean per le Action utilizzate da Struts2, devono seguire le convenzioni descritte nel paragrafo precedente. Inoltre anche i path di tutte le Actions devono essere strutturati in maniera da evitare sovrapposizioni con i path utilizzati nel Core o da altri Plugin.

Nella definizione di tutte le azioni si deve utilizzare la seguente sintassi:

  • I nomi dei namespace devono presentare nel path l'id del Plugin immediatamente dopo la stringa utilizzata per il mapping del filtro di Spring2.

    Example 4.4. Naming convention di una Struts2 Action

    /do/<PLUGIN_ID>/<SUB_PATH>


    Example 4.5. Un nome appropriato per una Strut2 Action

    /do/jpuserprofile/CurrentUser/edit.action


  • Gli identificativi dei packages devono essere nella forma <PLUGIN_ID>_do/<PLUGIN_ID>/<SUB_PATH>

    Example 4.6. Un id appropriato per un package di Azioni di Strut2

    jpuserprofile_do/jpuserprofile/CurrentUser


Nomi Tiles Definition (TilesPlugin di Struts2 Objects)

Per evitare sovrapposizioni con nomi utilizzati nel Core o da altri Plugin, tutti i nomi delle Tiles Definition delle interfacce devono presentare l'id del plugin come di seguito: admin.<PLUGIN_ID>.<FEATURE>.<NAME_OF_THE_VIEW>

i18n

Nel caso in cui il Plugin abbia delle interfacce per il front-end, devono essere fornite le apposite etichette (che sono i record della tabella localstrings erogati tramite custom tag wp:i18n). Es: le label dei form, sottotitoli, note introduttive ed esplicative varie.

Example 4.7. Qualche semplice labels per il frontend

  • jpuserprofile_SEARCH_FORM = Search
  • jpuserprofile_ADDRESS_COUNTRY = Country

Le stesse considerazioni valgono anche per le interfacce del back-end (in questo caso vanno forniti i files package_<LANG_CODE>.properties secondo quanto descritto nel documento jAPS 2.0 - Pattern di Creazione e Integrazione Servizi Applicativi). In particolare, sia le chiavi (codici) delle label del front-end che quelle delle label del back-end devono essere strutturate in maniera tale da evitare sovrapposizioni con quelle del core, per cui devono presentare come prefisso l'id del Plugin.

Example 4.8. Qualche semplice labels per il backend

  • jpuserprofile.mylabel = My really simple label
  • jpuserprofile.myarea.myotherlabel = This is a note, just like the one up there

Inoltre, per le interfacce di back-end, in ogni plugin deve essere predisposto un file di property di nome global-messages__<LANG_CODE>.properties nel package <DOMINIO_R>.plugins.<PLUGIN_ID>.apsadmin. In questo file devono essere inserire le label base del plugin (label di codice <PLUGIN_ID>.code e <PLUGIN_ID>.name), oltre ad eventuali altre label per le voci del menu generale Plugins.

Permessi

Nel caso in cui il Plugin introduca nuovi permessi, i loro id (che devono essere indicati nella tabella authpemissions) devono presentare come prefisso l'id del del Plugin seguito da un underscore (carattere _).

Nome Bean sub-menu Area di Amministrazione

L'identificativo del bean relativo al sub-menu della voce Plugins dell'area di amministrazione deve essere strutturato come di seguito: <PLUGIN_ID>SubMenu.

Tabelle Database

I nomi delle eventuali tabelle ad uso del plugin (inserite indifferentemente nel db *Port or *Serv) devono presentare come prefisso l'id del Plugin seguito da un underscore (carattere _).

Nomi Item di Configurazione (tabella sysconfig, DataBase *Port)

I nomi degli Item di configurazione devono presentare come prefisso il codice del Plugin seguito da un underscore (carattere _).