13.07.2015 Views

Thesis full text PDF - Untitled Document - Politecnico di Milano

Thesis full text PDF - Untitled Document - Politecnico di Milano

Thesis full text PDF - Untitled Document - Politecnico di Milano

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>Politecnico</strong> <strong>di</strong> <strong>Milano</strong> · Polo Regionale <strong>di</strong> ComoFACOLTÀ DI INGEGNERIA DELL’INFORMAZIONECorso <strong>di</strong> Laurea Magistrale in Ingegneria InformaticaManuale del ProgrammaWorkFlow DesignerRelatore:Prof. Marco BrambillaRealizzato da:Alessio AntoniniMatr. 673853Anno Accademico 2004-2005


In<strong>di</strong>ce1 Introduzione 12 Analisi dei requisiti 32.1 Gestione dell’albero dati . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32.2 Generazione degli Id’s degli oggetti . . . . . . . . . . . . . . . . . . . . . . 52.3 Navigazione attraverso i livelli . . . . . . . . . . . . . . . . . . . . . . . . . 52.4 Discriminazione sul tipo <strong>di</strong> livello . . . . . . . . . . . . . . . . . . . . . . . 53 Progettazione 63.1 I componenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 Commento del co<strong>di</strong>ce 84.1 Creazione <strong>di</strong> più viste aeree . . . . . . . . . . . . . . . . . . . . . . . . . . 84.2 Discriminazione sul tipo <strong>di</strong> livello . . . . . . . . . . . . . . . . . . . . . . . 125 Testing 215.1 Caso <strong>di</strong> applicazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215.1.1 Livello 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215.1.2 Livello 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225.1.3 Uso dei tabulatori . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245.1.4 Uso del menù <strong>di</strong> navigazione . . . . . . . . . . . . . . . . . . . . . . 245.1.5 Conclusioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256 Conclusioni e sviluppi futuri 26i


Capitolo 1IntroduzioneLo scopo <strong>di</strong> questo programma è fornire un ambiente <strong>di</strong> sviluppo grafico per l’implementazione<strong>di</strong> un WorkFlow.A tal fine si è realizzata l’applicazione WorkFlow Designer, che costituisce lanaturale evoluzione <strong>di</strong> un precedente progetto 1La scelta dello standard da adottare per la realizzazione dei <strong>di</strong>agrammi <strong>di</strong> workflow èricaduta sul linguaggio BPMN 2 .Il suddetto linguaggio permette <strong>di</strong> adottare una notazione grafica, che descriva le fasi<strong>di</strong> lavoro all’interno <strong>di</strong> un generico processo <strong>di</strong> business.Al fine <strong>di</strong> aumentare le potenzialità del programma preesistente si è introdotto ilconcetto <strong>di</strong> multilivello, peraltro già documentato nello standard BPMN.Per la realizzazione del suddetto scopo si è resa necessaria una sostanziale riproggettazionedel programma preesistente.1 Tesi <strong>di</strong> laurea in Ingegneria Informatica presso il <strong>Politecnico</strong> <strong>di</strong> <strong>Milano</strong>: SDSgraphicaltool a cura <strong>di</strong>Vignani e Riceputi, anno 2003/20042 Business Process Modeling Notation: serve a definire un Business Process Diagram (BPD), questo<strong>di</strong>agramma sarà un insieme <strong>di</strong> oggetti grafici collegati tra loro da frecce che rappresentano dei controlli<strong>di</strong> flusso, il cui scopo è quello <strong>di</strong> definire l’or<strong>di</strong>ne <strong>di</strong> svolgimento delle azioni. Questi oggetti consentonoil facile sviluppo <strong>di</strong> semplici <strong>di</strong>agrammi <strong>di</strong> flusso che hanno il pregio <strong>di</strong> risultare familiari ed intuitivialla maggior parte degli utenti che ne fanno uso (es. flowchart). Gli elementi che compongono il BPDsono stati definiti rispettando due criteri principali: il primo è che siano il più possibile <strong>di</strong>stinguibili unodall’altro; il secondo che la forma risulti il più possibile familiare. Le attività sono rettangolari mentre ledecisioni hanno la forma <strong>di</strong> rombi.1


Quin<strong>di</strong> il lavoro svolto consta delle seguenti fasi:1. analisi dei requisiti2. progettazione3. co<strong>di</strong>fica4. testingLe prime due fasi tengono in conto dei preesistenti requisiti e della loro implementazione,andandosi ad aggiungere come ulteriore rielaborazione.La co<strong>di</strong>fica avvenuta utilizzando l’ambiente <strong>di</strong> sviluppo Eclipse 3.0, verrà <strong>di</strong> seguitocommentata negli aspetti salienti.l’ultima fase è illustrata attraverso una demo del programma in funzione, documentataattraverso una sequenza <strong>di</strong> screens.2


Capitolo 2Analisi dei requisitiAllo scopo <strong>di</strong> aumentare le potenzialità del programma preesistente, con l’iserimento delmultilivello, si è fatto uno stu<strong>di</strong>o <strong>di</strong> progettazione che tiene in conto dei seguenti aspetti:• gestione dell’albero dati• generazione degli Id’s degli oggetti• navigazione attraverso i livelli• <strong>di</strong>scriminazione sul tipo <strong>di</strong> livello2.1 Gestione dell’albero datiIl meccanismo <strong>di</strong> generazione dei dati si serve del sistema illustrato in figura 2.1.Quin<strong>di</strong> il multilivello è implementato sfruttando la struttura dell’albero già implementatanel preesistente programma 1Si dovrà implementare una classe CreateSubProcess che permetta l’inserimento delleattività con sotto processi, come definite nel linguaggio BPMN.1 Non si esclude la possibiltà futura <strong>di</strong> mo<strong>di</strong>ficare l’albero utilizzando altri costrutti Java.3


2.1. Gestione dell’albero datiFigura 2.1: Struttura dell’albero e multilivello.4


2.2. Generazione degli Id’s degli oggetti2.2 Generazione degli Id’s degli oggettiLa gestione degli Id’s degli oggetti è un punto delicato, in quanto ad ogni nuova istanza<strong>di</strong> WFDInternalFrame il loro conteggio non si deve azzerare.Questa è una problematica rinvenibile solamente in una struttura multilivello, ove ogniInternlFrame è un livello.La soluzione adottada è quella <strong>di</strong> azzerare i contatori ad ogni new project.2.3 Navigazione attraverso i livelliBisogna poter <strong>di</strong>scriminare tra i <strong>di</strong>versi livelli, ad esempio con l’inserimento <strong>di</strong> un menùwindow che permetta <strong>di</strong> selezionare il sotto-livello (sub-process) <strong>di</strong> lavoro.Per agevolare l’utente <strong>di</strong> provvederà all’inserimento <strong>di</strong> più viste aeree ( AeroCanvas )nonchè <strong>di</strong> un sistema a tabulatori che permetta <strong>di</strong> vedere la vista aerea <strong>di</strong> tutti i relativipadri <strong>di</strong> ogni sottolivello.2.4 Discriminazione sul tipo <strong>di</strong> livelloNell’implementazione della funzionalità multilivello, è <strong>di</strong> sicuro interesse, al fine <strong>di</strong> sviluppifuturi, il poter <strong>di</strong>fferenziare i tipi <strong>di</strong> primitive <strong>di</strong>sponibili per ogni nuovo livello.In pratica nel caso si vogliano poter aggiungere, ad un determinato livello, oggetti<strong>di</strong>versi dallo standard BPMN, il programa deve poter permettere questa opzione.5


Capitolo 3ProgettazioneIl programma realizzato ha come core le seguenti tre classi:1. WFDManager: contiene il main e si occupa della gestione dei dati e della GUI.2. WFDMainframe: realizza il desktop e la menuBar.3. WFDInternalFrame: realizza l’area <strong>di</strong> lavoro.Possiamo quin<strong>di</strong> definire il Class Diagramm riportato in figura 3.1.3.1 I componentiIl programma necessita <strong>di</strong> un Manager : WFDManager (utilizzo del pattern singleton)che gestisce l’intero progamma.Dovremo avere una classe WFDMainFrame che rappresenta il desktop del programma, in avvio vuoto ( almeno prima <strong>di</strong> fare un nuovo progetto o caricarne uno esistente ).WFDMainFrame conterrà 0 o N istanze <strong>di</strong> WFDInternalFrame (multilivello) ; ogniWFDInternalFrame avrà un’unica instanza delle classi InfoTabPanel, ScrollableCanvas epiù istanze <strong>di</strong> AeroCanvas. Lo stesso conterrà pure le istanze delle classi Create.Nelle classi che creano gli oggetti ( activity ecc..) viene passato il WFDInternalFrame<strong>di</strong> riferimento. Ovvero devono essere legati al proprio InternalFrame.6


3.1. I componentiFigura 3.1: Class Diagramm.7


Capitolo 4Commento del co<strong>di</strong>ceIn questa parte vengono riportati dei frammenti <strong>di</strong> co<strong>di</strong>ce relativi agli aspetti implementativipiù salienti.4.1 Creazione <strong>di</strong> più viste aereePassiamo ad esaminare come avviene la creazione <strong>di</strong> più viste aeree.✞Per creare un InternalFrame usiamo la classe WFDInternalFrame:WFDMainFrame . addNewInternalFrame✡✝✆Per costruire un nuovo InternalFrame ( ad esempio IF1 ) gli viene passato l’InternalFramepadre (IF0):✞/∗ c r e a t e a e r e a l view panel ∗/// s i fa dare d a l l ’ InternalFrame padre// t u t t i g l i aerocanvas// e ne r i c h i e d e l a c l o n a z i o n eJTabbedPane tabPane = new JTabbedPane ( ) ;c o n t r o l P a n e l . add ( tabPane ) ;i f ( parentIntFrame != null ) {8


4.1. Creazione <strong>di</strong> più viste aereeL i s t l = parentIntFrame . getShownAeroCanvasList ( ) ;for ( int i = 0 ; l != null && i < l . s i z e ( ) ; i++){AeroCanvas ae = ( AeroCanvas ) l . get ( i ) ;ae = ( AeroCanvas ) ae . c l o n e ( ) ;JPanel viewPanel = new JPanel (new BorderLayout ( ) ) ;viewPanel . add ( ae , BorderLayout .CENTER) ;// a t t a c c a l ’ aerocanvas <strong>di</strong> ogni padre}}ae . updateView ( ) ;/∗ c r e a t e aeroCanvas ∗/✡✝// aeroCanvas = n u l l ;aeroCanvas = createNewAeroCanvas ( ) ; // nota1JPanel viewPanel = new JPanel (new BorderLayout ( ) ) ;viewPanel . add ( aeroCanvas , BorderLayout .CENTER) ;// a t t a c c a l ’ aerocanvas <strong>di</strong> se s t e s s o. . . . . . . .tabPane . add ( viewPanel , ”” + aeroCanvas . getLevel ( ) ) ;tabPane . s e t S e l e c t e d I n d e x ( tabPane . getComponentCount ( ) − 1 ) ;✆L’InternalFrame 1 chiede a InternalFrame 0 la clonazione <strong>di</strong> tutti gli Aerocanvasmostrati da InternalFrame 0:✞[ ae = ( AeroCanvas ) ae . c l o n e ( ) ; ]✡✝✆9


4.1. Creazione <strong>di</strong> più viste aereeOgni ae (AeroCanvas) per clonarsi, chiede al proprio InternalFrame creatore <strong>di</strong> fareuna copia:✞AeroCanvas . c l o n e ( ) => return intFrame . createNewAeroCanvas ( ) ;✡✝✆L’InternalFrame quando crea un nuovo “ae”, lo fa passando il riferimento a se stesso;in questo modo ogni “ae” ha il riferimento verso il proprio creatore.Inoltre InternalFrame tiene traccia in una lista <strong>di</strong> tutti gli AE creati. Questo serveper aggiornare tutti gli AeroCanvas che mostrano l’InternalFrame che é stato mo<strong>di</strong>ficato.✞✡✝public AeroCanvas createNewAeroCanvas ( ) {AeroCanvas ac = new AeroCanvas ( this ) ;createdAeroCanvasList . add ( ac ) ;return ac ;}✆L’aggiornamento degli AeroCanvas avviene invocando il metodo updateAllAeroCanvas()della classe WFDInternalFrame.Tornando alla creazione del nuovo InternalFrame, dopo aver chiesto all’InternalFramepadre la clonazione dei suoi AeroCanvas mostrati, il nuovo InternalFrame deve crearsi ilsuo nuovo AeroCanvas.10


4.1. Creazione <strong>di</strong> più viste aereeIn figura 4.1 è schematizzato il meccanismo appena spiegato al fine <strong>di</strong> offrire unamaggiore chiarezza:Figura 4.1: Aerocanvas.11


4.2. Discriminazione sul tipo <strong>di</strong> livello4.2 Discriminazione sul tipo <strong>di</strong> livelloQuando viene creato un Subprocess, se il livello non esiste ancora viene chiesto all’utenteil suo tipo.Il tipo <strong>di</strong> un livello è caratterizzato da un sottoinsieme <strong>di</strong> tools 1 <strong>di</strong>sponibili.I tipi a <strong>di</strong>sposizione sono descritti nel file levelTypes.properties. Questo file <strong>di</strong>property ha come chiave il nome del tipo e come valore una stringa contenente i nomi deitools a <strong>di</strong>sposizione separati da una virgola.Questo potrebbe essere un esempio <strong>di</strong> oggetti <strong>di</strong>sponibili e seconda che il tipo <strong>di</strong> livellosia : all o sub set es 2 :all = Lane,Start,End,Activity,SubProcess,And,Or,Xor,Data,Linksub set es = Lane,Start,End,Activity,Data,LinkIl metodo che si occupa del caricamento dei tipi a <strong>di</strong>sposizione è:WFDManager.loadLevelConfigurations.Attraverso il co<strong>di</strong>ce che segue viene letto il file <strong>di</strong> properties riempiendo una nuovaHashMap (levelTypes) (stringa,ArrayList); come chiave usa la stringa contenente il nomedel tipo, come valore non più una sringa ma un ArrayList contenente i nomi dei tools a<strong>di</strong>sposizione; questa scelta è comoda perché è più semplice scan<strong>di</strong>re un ArrayList piuttostoche “tokenizzare” un stringa separata da virgole.✞/∗∗∗ Loads the l e v e l c o n f i g u r a t i o n f i l e s ,∗ c o n t a i n i n g the l e v e l s t y p e s and∗ f o r each l e v e l the a v a i l a b l e t o o l s∗∗/private void l o a d L e v e l C o n f i g u r a t i o n s ( ){// f i l l l e v e l T y p e s : key = l e v e l type name ( S t r i n g ) ,// v a l u e = a v a i l a b l e t o o l s ( Set of S t r i n g s )// e . g . ” Level1 ” {”And” , ” A c t i v i t y ” , ”End ” . . . }1 Per tools inten<strong>di</strong>amo gli oggetti grafici offerti dal linguaggio BPMN; ma potrebbero anche essereoggetti specificati sencondo un qualsiasi altro standard per rappresentare WorkFlow2 i nomi dei livelli sono del tutto arbitrari ed a solo scopo <strong>di</strong> esempio12


4.2. Discriminazione sul tipo <strong>di</strong> livelloP r o p e r t i e s prop = new P r o p e r t i e s ( ) ;try {FileInputStream configStream =new FileInputStream (LEVEL TYPES CONFIG FILE ) ;prop . load ( configStream ) ;configStream . c l o s e ( ) ;for ( I t e r a t o r i t = prop . keySet ( ) . i t e r a t o r ( ) ; i t . hasNext ( ) ; ){S t r i n g key = ( ( S t r i n g ) i t . next ( ) ) . trim ( ) ;S t r i n g value = ( S t r i n g ) prop . get ( key ) ;L i s t l i s t = new ArrayList ( ) ;StringTokenizer s t = new StringTokenizer ( value , ” , ” ) ;while ( s t . hasMoreTokens ( ) ) {S t r i n g token = s t . nextToken ( ) . trim ( ) ;l i s t . add ( token ) ;}levelTypes . put ( key , l i s t ) ;}✡✝}} catch ( IOException e ) {levelTypes = new HashMap ( ) ;System . out . p r i n t l n (” Error : Cannot load c o n f i g u r a t i o n f i l e ’ ”+ LEVEL TYPES CONFIG FILE+ ” ’ ” ) ;}✆13


4.2. Discriminazione sul tipo <strong>di</strong> livelloQuin<strong>di</strong> la classe ChooseLebvelDialog può mostrare all’utente l’elenco dei tipi a <strong>di</strong>sposizionee per ogni tipo mostra i tools a <strong>di</strong>sposizione scandendo l’ArrayList.✞public class ChooseLevelDialog extends JDialog{private S t r i n g type ;/∗∗∗ Creates a new i n s t a n c e of t h i s c l a s s .∗/public ChooseLevelDialog ( Frame ownerFrame , int l e v e l ){. . . . . .initComponents ( ) ;}private void initComponents ( ){/∗ c r e a t e content pane ∗/. . . . . ./∗ o r g a n i z e t y p e s ∗/Map levelTypes = WFDManager . g e t I n s t a n c e ( ) . getLevelTypes ( ) ;// recupero l a mappa d e i l i v e l l i✡✝L i s t typeNames = new ArrayList ( levelTypes . keySet ( ) ) ;// recupero l ’ elenco d e l l e c h i a v i ,// ovvero I nomi d e i t i p i d e i l i v e l l i✆14


4.2. Discriminazione sul tipo <strong>di</strong> livelloVengono scan<strong>di</strong>ti i nomi dei tipi e per ognuno <strong>di</strong> questi viene creato un bottone; glisi attacca l’implementazione dell’interfaccia ActionListener facendo in modo che quandol’utente preme il bottone rapresentante il tipo desiderato registra nela variabile type (attributo privato dela classe ChooseLevelDialog) il nome del tipo a cui il bottone fa riferimento:✞for ( I t e r a t o r i t = typeNames . i t e r a t o r ( ) ; i t . hasNext ( ) ; ){// buttonf i n a l S t r i n g name = ( S t r i n g ) i t . next ( ) ;JButton button = new JButton (name ) ;button . setBackground (WFDManager . d e f a u l t C o l o r ) ;button . addActionListener (new A c t i o n L i s t e n e r ( ) {public void actionPerformed ( ActionEvent e ) {type = name ;s e t V i s i b l e ( f a l s e ) ;}} ) ;westPanel . add ( button ) ;// iconsL i s t l i s t = ( L i s t ) levelTypes . get (name ) ;// recupero ArrayList contenente i// nomi d e i t o o l s a d i s p o s i z i o n e✡✝✆Creazione del pannello:✞// s i s c a n d i s c e l a l i s t ae per ognuno d e i nomi// chiedo a l Manager <strong>di</strong> r e s t i t u i r e l ’ image icon r a p p r e s e n t a n t e i l// t o o lfor ( I t e r a t o r i t 2 = l i s t . i t e r a t o r ( ) ; i t 2 . hasNext ( ) ; ){S t r i n g s = ( S t r i n g ) i t 2 . next ( ) ;15


4.2. Discriminazione sul tipo <strong>di</strong> livelloImageIcon imageIcon =WFDManager . g e t I n s t a n c e ( ) . getImageIconFor ( s ) ;JLabel label = new JLabel ( imageIcon ) ;iconPanel . add ( label ) ;i f ( i t 2 . hasNext ( ) ) {iconPanel . add (Box . c r e a t e H o r i z o n t a l S t r u t ( 5 ) ) ;}centerPanel . add ( iconPanel ) ;}}✡✝pack ( ) ;✆Il seguente frammento <strong>di</strong> co<strong>di</strong>ce ritorna il tipo al Manager che lo usa per definire iltipo <strong>di</strong> livello quando questo livello viene utilizzato per la prima volta:✞}✡✝/∗∗∗ Returns the choosen type .∗/public S t r i n g getType ( ) {}return type ;✆16


4.2. Discriminazione sul tipo <strong>di</strong> livelloNel Manager c’è una mappa ( levelMap ) che per ogni livello contiene il suo tipo (chiave=Integer, valore=stringa ):✞/∗∗∗ Shows a d i a l o g containg the a v a i l a b l e l e v e l type∗ with t o o l s and r e t u r n s a s e t containg the∗ a v a i l a b l e t o o l s f o r the choosen l e v e l type .∗/public L i s t chooseAvailableTools ( int l e v e l ) {. . . .S t r i n g type = null ;L i s t r e s = null ;I n t e g e r l e v = new I n t e g e r ( l e v e l ) ;. . . . .i f ( levelMap . get ( l e v ) != null ) {type = ( S t r i n g ) levelMap . get ( l e v ) ;} else {ChooseLevelDialog d i a l o g =new ChooseLevelDialog ( getMainFrame ( ) , l e v e l ) ;d i a l o g . s e t V i s i b l e ( true ) ;type = d i a l o g . getType ( ) ;levelMap . put ( lev , type ) ;// i l type è r e s t i t u i t o// d a l l a c l a s s e ChooseLevelType}r e s = ( L i s t ) levelTypes . get ( type ) ;// s i recuperano i t o o l s r e l a t i v i// a l type v o l u t o per i l l i v e l l o}✡✝return r e s ;✆17


4.2. Discriminazione sul tipo <strong>di</strong> livello✞La creazione <strong>di</strong> un nuovo InternalFrame viene fatta dalla seguente classe:Classe CreateSubProcessprivate void createNewInternalFrame ( ) {int nextLevel = intFrame . getLevel ( ) + 1 ;L i s t enableTools = WFDManager . g e t I n s t a n c e ( ). chooseAvailableTools ( nextLevel ) ;GFNode gfNode = new GFNode( ”Group DataObj” , null , null ) ;treeSubProcess . add (new DefaultMutableTreeNode ( gfNode ) ) ;newIntFrame = WFDManager . g e t I n s t a n c e ( ) . getMainFrame ( ). addNewInternalFrame ( treeSubProcess ,nodeSubProcess . getID ( ) ,nextLevel , enableTools , intFrame ) ;gfNode . setInternalFrame ( newIntFrame ) ;// a s s o c i a a l l a root d e l s o t t o a l b e r o// i l nuovo InternalFrame✡✝}intFrame . g e t P a l e t t e ( ) . s e t D e f a u l t T o o l ( ) ;✆Creazione <strong>di</strong> un nuovo progetto:✞/∗∗ Create a new p r o j e c t ∗/public WFDInternalFrame newProject ( ) {// i n i t mappai f ( levelMap != null ) {levelMap . c l e a r ( ) ;levelMap = null ;}levelMap = new HashMap ( ) ;// c r e a z i o n e a l b e r o vuoto18


4.2. Discriminazione sul tipo <strong>di</strong> livellop r o j e c t T r e e = new DefaultMutableTreeNode( ” Tree f o r the Domain Model” ) ;GFNode gfNode = new GFNode( ”Group DataObj” , null , null ) ;p r o j e c t T r e e . add (new DefaultMutableTreeNode ( gfNode ) ) ;// svuota l a mappa d e i GO ( key=GFNode , v a l u e = GO)nodeGODict . c l e a r ( ) ;// svuota i l desktopgetMainFrame ( ) . removeAllInternalFrames ( ) ;// crea nuovo InternalFrame p a s s a n d o g l i// i l nuovo p rojectTreeWFDInternalFrame intFrame =getMainFrame ( ) . addNewInternalFrame (projectTree ,”Main Diagram” ,0 ,null ,null ) ;gfNode . setInternalFrame ( intFrame ) ;// s e t t a i l nome d e l p r o g e t t o✡✝}setProjectName ( ” U n t i t l e d ” ) ;return intFrame ;✆Caricamento <strong>di</strong> un progetto:✞F i l e L i s t e n e r . a c t i o n L i s t e n e r ( ActionEvent e )// crea nuovo p r o g e t t oWFDInternalFrame intFrame =19


4.2. Discriminazione sul tipo <strong>di</strong> livelloWFDManager . g e t I n s t a n c e ( ) . newProject ( ) ;// recupera i l nome d e l f i l eS t r i n g nameFile = openFile . getAbsolutePath ( ) ;// l e g g e I l i v e l l i d a l f i l e// Memorizza n e l \emph{WFDManager} per ogni// l i v e l l o i l t i p o a s s o c i a t o// ( es . l i v e l l o 2 , t i p o l e v e l p i p p o )// invocando i l metodo addToLevelMap// d e l l a c l a s s e WFDManager i l q u a l e riempie// l a mappa levelMap :levelMap . put ( lev , type ) ;LoadProjectLevels . parse ( nameFile ) ;// q u esto metodo r i c e v e l ’ InternalFrame e// s i fa dare da q u e s t i i v a r i t o o l per// creare I v a r i o g g e t t i ;// mantiene a g g i o rnata l a mappa nodeGODict// che fa r i f e r i m e n t o a l l a mappa GFNodeGO// a l l a f i n e t r a c c i a t u t t i i l i n k t r a g l i o g g e t t i✡✝OpenToolXml . parse (nameFile ,nodeGODict ,( Vector ) attrTable . get ( ” Link ” ) ,intFrame ) ;20✆


Capitolo 5TestingIn quest’ultima fase ci occuperemo <strong>di</strong> mostrare attraverso un esempio reale l’utilizzo dellefunzionalità del programma allo stato <strong>di</strong> sviluppo attuale.Questo ci permetterà anche <strong>di</strong> evidenziare eventuali malfunzionamenti, scopo principale<strong>di</strong> un testing.5.1 Caso <strong>di</strong> applicazioneSi vuole rappresentare un WorkFlow relativo alla richiesta <strong>di</strong> un prestito da parte <strong>di</strong> unprivato nei confronti <strong>di</strong> una società finanziaria.Il caso in esame presenta due possibili livelli.5.1.1 Livello 0Nel primo livelo abbiamo 3 attori:1. il cliente: colui che rischiede il prestito2. il manager: il funzionario responsabile dei prestiti della società fininziaria3. l’impiegato: colui che effettua i controlli patrimoniali e lavorativi suiclienti.Abbiamo 4 attività elementari:1. la richiesta <strong>di</strong> finanziamento: avanzata dal cliente nei confronti delmanager2. la validazione preliminare: effettuata dal manager21


5.1. Caso <strong>di</strong> applicazione3. il controllo finanziario: demandato dal manager all’ìimpiegato4. l’approvazione finale: rilasciata dal managerVi è inoltre un’attività con sottoprocesso:5. il controllo dell’attività lavorativa: effettuato da un ente terzo surichiesta dell’impiegato della società finanziaria.In figura 5.1 è riportato lo screen della situazione appena descritta, modellata conWFD.Figura 5.1: Prestito: livello 0.5.1.2 Livello 1Nel secondo livelo abbiamo 1 attore:4. l’impiegato: della società per cui lavora il cliente, che a seguito <strong>di</strong> richiestada perte della società finanziaria effettua un controllo sullo statolavorativo.22


5.1. Caso <strong>di</strong> applicazioneVi è una ulteriore attività elementare:6. ilcontrollo della posizione del cliente: ovvero proprio l’attività <strong>di</strong> verificasulla situazione lavorativa del cliente da parte dell’ente per cuilavora.In figura 5.2 è riportato lo screen della situazione appena descritta, modellata conWFD.Figura 5.2: Prestito: livello 1.23


5.1. Caso <strong>di</strong> applicazione5.1.3 Uso dei tabulatoriIn figura 5.3 è riportato uno screen che mostra come sia possibile attraverso i tabulatori,pur restando nel livello 1, vedere l’aerocanvas del livello 0.Figura 5.3: Uso dei tabulatori5.1.4 Uso del menù <strong>di</strong> navigazioneEsistono inoltre molte possibilità per navigare atraverso i livelli:• menù “window”• pulsante per il “back”• doppio click sul subprocess24


5.1. Caso <strong>di</strong> applicazioneIn figura 5.4 è riportato uno screen che mostra le tre possibilità:Figura 5.4: Navigazione5.1.5 ConclusioniIl testing non ha evidenziato particolari problemi per quel che riguarda le funzionalitàimplementate, tuttavia, non potendosi escludere la presenza <strong>di</strong> “bachi”, si consiglia aipossibili utilizzatori <strong>di</strong> effettuare un periodo <strong>di</strong> beta-testing.25


Capitolo 6Conclusioni e sviluppi futuriIl programma, allo stato attuale permette:• la realizzazione <strong>di</strong> progetti multilivello• il salvataggio e il caricamento dei progetti in formato XML• la generazione del LTL ( Linear Temporal Logic )• la visualizzazione aerea multilivello• la possibilità <strong>di</strong> <strong>di</strong>fferenziare la tipologia <strong>di</strong> livelloL’applicazione consente <strong>di</strong> effettuare ulteriori migliorie ed ampliamenti <strong>di</strong> funzionalità.Tra i possibili sviluppi futuri, si evidenzia la possibilità <strong>di</strong>:• aggiugere ulteriori oggetti del linguaggio BPMN.• progettare ben definite tipologie <strong>di</strong> livelli alternativi al BPMN.• semplificare la struttura dell’albero dati attraverso opportuni costruttijava alternativi ( tipo DOM - <strong>Document</strong> Object Model ).• migliorare alcune funzionalità dell’interfaccia utente.26

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!