Analiza Software a Sistemului

Cuprins

1. Introducere 4

1.1 Structura capitolelor 4

2. Definirea problemei 5

2.1 Descrierea problemei 5

2.2 Obiectivele sistemului 5

2.3 Participanți 5

2.4 Scenarii de bază 6

3. Analiza software a sistemului 7

3.1 Documentul de cerințe 7

3.1.1 Descrierea sistemului Event-Hub 7

3.1.2 Actori 7

3.1.3 Cerințele sistemului Event-Hub 7

3.1.4 Cerințe nefuncționale 9

3.2 Modelul funcțional 10

3.2.1 Cazul de utilizare: Creare cont 10

3.2.2 Cazul de utilizare: Autentificare în sistem 11

3.2.3 Cazul de utilizare: Adăugare eveniment 11

3.2.4 Cazul de utilizare: Vizualizare evenimente 12

3.2.5 Cazul de utilizare: Selectare preferințe 13

3.2.6 Cazul de utilizare: Notificare utilizatori 13

3.2.7 Cazul de utilizare: Rezervare bilete 13

3.2.8 Diagrama cazurilor de utilizare 14

3.3 Diagrame de secvențe de sistem 16

3.3.1 Diagrama cazului de utilizare: Creare cont 18

3.3.2 Diagrama cazului de utilizare: Autentificare în sistem 19

3.3.3 Diagrama cazului de utilizare: Adăugare eveniment 20

3.3.4 Diagrama cazului de utilizare: Vizualizare eveniment 21

3.3.5 Diagrama cazului de utilizare: Selectare preferințe 22

3.3.6 Diagrama cazului de utilizare: Rezervare bilet 23

3.4 Modelul domeniului 24

3.4.1 Diagrama de clase 24

4. Proiectarea și implementarea aplicației 27

4.1 Arhitecturi software 27

4.1.1 Stilul arhitectural Client-Server 27

4.1.2 Stilul arhitectural pe straturi 27

4.1.3 Stilul arhitectural Model-View-Controller 28

4.2 Modele de proiectare 29

4.2.1 Controller 29

4.2.2 Creator 29

4.2.3 Information Expert 29

4.2.4 High Cohesion 30

4.2.5 Low Coupling 30

4.2.6 Indirection 30

4.2.7 Polymorphism 30

4.2.8 Protected Variations 30

4.2.9 Pure Fabrication 31

4.3 Diagrame de interacțiuni 31

4.3.1 Diagrama de interacțiuni a cazului de utilizare: Creare Cont 32

4.3.2 Diagrama de interacțiuni a cazului de utilizare: Autentificare în sistem 33

4.3.3 Diagrama de interacțiuni a cazului de utilizare: Adăugare Eveniment 34

4.3.4 Diagrama de interacțiuni a cazului de utilizare: Vizualizare eveniment 35

4.3.5 Diagrama de interacțiuni a cazului de utilizare: Selectare preferințe 36

4.3.6 Diagrama de interacțiuni a cazului de utilizare: Rezervare bilet 37

4.4 Diagrame de clase de proiectare 38

4.4.1 Diagrama de clase de proiectare a cazului de utilizare: Creare Cont 39

4.4.2 Diagrama de clase de proiectare a cazului de utilizare: Autentificare în sistem 40

4.4.3 Diagrama de clase de proiectare a cazului de utilizare: Adăugare eveniment 41

4.4.4 Diagrama de clase de proiectare a cazului de utilizare: Vizualizare eveniment 42

4.4.5 Diagrama de clase de proiectare a cazului de utilizare: Selectare preferințe 43

4.4.6 Diagrama de clase de proiectare a cazului de utilizare: Rezervare bilet 44

4.5 Proiectarea bazei de date 45

4.6 Implementarea aplicației 48

4.6.1 Conexiunea dintre Client și Server 48

4.6.2 Conexiunea la baza de date 52

4.6.3 Creare cont și Autentificare în sistem 53

4.6.4 Adăugare eveniment și Notificare utilizatori 57

4.6.5 Vizualizare eveniment și Rezervare bilet 62

5. Concluzii 74

6. Anexe 75

6.1 Trigger SQL 75

6.2 Procedură SQL 75

Bibliografie 79

Introducere

Lucrarea de față propune o soluție accesibilă unui număr mare de utilizatori pentru a sta la curent cu ultimele evenimente culturale, precum și organizatorilor de a promova cu ușurință aceste evenimente.

Soluția prezentă se concretizează într-o aplicație ce permite utilizatorilor acces la evenimentele curente, detaliile acestora și opțiunea de a rezerva bilete. Totodată ei pot opta pentru sistemul de notificare prin email chiar și atunci când aplicația este închisă.

Structura capitolelor

Conținutul lucrării este împărțit pe 5 capitole după cum urmează.

Primul capitol conține o scurtă prezentare a subiectului abordat și a conținutului lucrării.

Al doilea capitol reprezintă definirea succintă a problemei abordate în care identificăm obiectivele pe care sistemul trebuie să le rezolve, participanții la procesul de dezvoltare și potențialele situații de utilizare.

Al treilea capitol constituie o analiză a sistemului software în care obiectivele stabilite anterior se concretizează în cerințe și cazuri de utilizare în documentul de cerințe și modelul funcțional. Se identifică tot aici conceptelor cheie a domeniului problemei și se realizează o vizualizare structurată în cadrul modelului domeniului.

Al patrulea capitol conține proiectarea sistemului software urmată de implementarea acestuia. Aici apar detalii precum stilurile arhitecturale folosite și identificarea componentelor cu apartenență la domeniul soluției. Acest capitol reprezintă produsul final din punct de vedere al aplicației dar și al bazei de date folosite.

Al cincilea și ultimul capitol conține o serie de concluzii pe urma celor prezentate.

Definirea problemei

Descrierea problemei

Un antreprenor intenționează să transmită publicului informații cu privire la diverse evenimente culturale prin intermediul unei sistem software. Acesta accesează sistemul pe partea de server cu o parolă de administrator pe care o poate schimba. Ca administrator al acestui sistem, el va introduce prin intermediul formularelor evenimentele cu detaliile aferente acestora cât și categoriile din care fac parte.

Fiecare utilizator va avea acces la sistem prin intermediul unui cont unic cu nume de utilizator bazat pe adresa de email și parolă pe care îl poate crea la pornirea aplicației. Acest cont va fi folosit pentru a se identifica în sistem la începutul fiecărei sesiuni de lucru în parte cu opțiunea ca aplicația să poată memora de la o sesiune la alta numele de utilizator dar nu și parola.

Prin intermediul acestui cont un utilizator poate opta pentru notificări personalizate pe anumite categorii generale sau specifice de evenimente odată ce acestea devin disponibile. Mai precis, utilizatorul se înregistrează la categoriile culturale de evenimente (muzică, film, expoziții de artă, etc) sau poate să specifice evenimentele la care vrea să participe și din acest motiv, vrea să fie notificat prin intermediul email-ului de data la care va avea loc și alte informații de interes (loc, preț bilet, etc). De exemplu, dacă utilizatorul este interesat să meargă la festivalul Untold, se va înregistra în aplicație să fie anunțat când va avea loc și când sunt puse în vânzare bilete la acest festival. Ulterior, utilizatorul își poate rezerva un loc primind în schimb un bilet electronic pe care îl poate printa utilizând imprimanta proprie.

Obiectivele sistemului

Soluția abordată în această lucrare are ca scop crearea unui mediu sigur și ușor de utilizat pentru toți utilizatorii sistemului informatic. Obiectivul principal este acela de a promova eficient evenimentele culturale gestionate de antreprenor printr-o experiență croită pe nevoile personale ale fiecărui utilizator. Obiectivele ce duc la înfăptuirea acestui scop sunt următoarele:

Autentificarea utilizatorilor prin cont unic

Memorarea preferințelor fiecărui utilizator

Gestionarea evenimentelor și categoriilor de care aparțin

Notificarea utilizatorilor în funcție de preferințe

Punerea la dispoziție de bilete pentru evenimentele disponibile

Participanți

Participanții sistemului informațional sunt toate acele persoane care sunt influențate într-o măsură sau alta sau care manifestă o influență, fie ea directă sau indirectă, asupra procesului de dezvoltare și de utilizare. Aceste persoane se clasifică în mai multe categorii.

Dezvoltatorii sunt considerați participanți deoarece au un rol activ în procesul de dezvoltare și astfel o influență directă asupra produsului final. În general, aceștia sunt de 3 tipuri:

Analist: întocmește documentele și cerințele de bază ale procesului de dezvoltare în conformitate cu analiza obiectivelor și descrie pe larg funcționalitățile aplicației;

Proiectant: stabilește arhitectura software atât a sistemului cât și a bazei de date;

Programator: implementează aplicația după modelele realizate de către proiectant și analist.

Participanții care nu sunt dezvoltatori se pot clasifica în participanți interni și participanți externi. În cazul de față, participant intern este considerat antreprenorul deoarece este beneficiarul direct al sistemului software iar participanții externi sunt toți clienții acestuia care vor folosi aplicația ulterior.

Scenarii de bază

În cele ce urmează vom prezenta un scenariu practic și modul în care se va interacționa cu sistemul pentru a evidenția funcționalitatea acestuia.

Presupunem că domnul Popescu Vasile este organizator și administratorul sistemului Event-Hub, iar domnul Lucian Ion este client.

Domnul Lucian Ion dorește să folosească sistemul Event-Hub pentru a fi la curent cu ultimele evenimente din zona în care locuiește. Pentru aceasta, el accesează aplicația și este întâmpinat cu un meniu principal care îi oferă 2 opțiuni: de a-și crea un cont și de a se autentifica. Pentru început, domnul Lucian Ion își creează un cont introducând datele sale personale precum numele, prenumele și adresa de email și alegându-și o parolă. Odată contul creat, clientul se poate autentifica folosind emailul său și parola introdusă la etapa anterioară.

După autentificarea în sistem, domnul Lucian Ion are posibilitatea de a vedea evenimentele deja a-și asocia contului un set de preferințe pe baza cărora să fie notificat. El realizează acest lucru selectând textul conținut în numele sau în descrierea evenimentului, localitatea sau județul în care are loc acesta, categoria din care face parte și/sau perioada de timp în care are loc.

Ulterior, domnul Popescu Vasile dorește să adauge un eveniment în baza de date a sistemului. Fiind organizator al sistemului, acesta are deja un cont privilegiat în acest sens pe care îl folosește pentru a se autentifica. Aplicația apoi îi prezintă o interfață grafică ușor de utilizat în care poate introduce evenimentul cu detaliile acestuia precum și categoriile de bilete pe care vrea să le facă disponibile.

După adăugarea evenimentului, dacă acesta se aplică criteriilor de preferințe ale lui Lucian Ion, acesta este notificat prin email de apariția noului eveniment, moment în care el se poate autentifica în aplicație cu scopul de a-și rezerva un bilet la evenimentul respectiv. Pentru aceasta el accesează lista de evenimente, îl alege pe cel dorit și își selectează unul sau mai multe locuri. Aplicația apoi îi afișează detaliile rezervării și îi cere o confirmare, ulterior căreia sistemul îi oferă opțiunea de a imprima biletul pe loc sau de a-l salva într-un document.

Acum, clientul Lucian Ion poate merge cu biletul imprimat pe care se află detaliile aferente la eveniment, asigurându-se că are locul rezervat din timp.

Analiza software a sistemului

Documentul de cerințe

Analiza sistemului este o activitate de bază în dezvoltarea oricărui sistem software. In timpul analizei sunt construite mai multe documente și modele ale viitorului sistem.

Unul din documentele create în timpul analizei software este documentul de cerințe care conține activitățile ce vor fi realizate de sistem sub formă de cerințe funcționale. Alături de aceste cerințe, sunt identificate proprietăți ale sistemului per ansamblu descrise sub formă de cerințe nefuncționale.

Împreună ele constituie cerințe de bază în procesul de dezvoltare ale sistemului software.

Descrierea sistemului Event-Hub

Sistemul Event-Hub permite introducere unui eveniment alături de informațiile legate de acesta precum locația, data și ora la care are loc precum și categoriile de bilete disponibile. Un client își poate face un cont folosind adresa de email iar în funcție de preferințele selectate va fi notificat prin email cu privire la evenimentele nou adăugate. Ulterior el poate realiza rezervări prin intermediul aplicației care îi va imprima un bilet folosind imprimanta propria a clientului.

Actori

Un actor software este o abstractizare care definește unul sau mai multe roluri ale unui utilizator sau a unui grup de utilizatori externi ce comunică în mod direct cu sistemul software. Mulțimea tuturor actorilor descrie astfel toate modalitățile în care utilizatorii interacționează cu sistemul software.

Sistemul Event-Hub are 2 actori software: utilizator și administrator.

Cerințele sistemului Event-Hub

F1. Creare de conturi

F1.1 Afișează opțiunea de ”creare cont”

F1.2 Permite alegerea opțiunii de ”creare cont”

F1.3 Solicită introducerea datelor (nume de utilizator, parolă, adresă de email)

F1.4 Permite introducerea datelor

F1.5 Verifică unicitatea numelui de utilizator

F1.6 În cazul in care numele de utilizator introdus este deja atribuit unui cont existent, atunci afișează un mesaj specific nepermițând crearea unui alt cont cu același nume de utilizator și solicită un altul diferit

F1.7 În cazul în care numele de utilizator s-a dovedit a nu fi atribuit unui cont existent, atunci memorează datele contului și afișează un mesaj specific

F2. Autentificare în sistem

F2.1 Afișează opțiunea de ”autentificare”

F2.2 Permite alegerea opțiunii de ”autentificare”

F2.3 Solicită introducerea numelui de utilizator și a parolei

F2.4 Permite introducerea datelor

F2.5 Preia și verifică validitatea datelor introduse

F2.6 În cazul în care nu există un cont cu numele de utilizator introdus, atunci afișează un mesaj specific și permite crearea unui cont folosind informațiile deja introduse

F2.7 În cazul în care parola introdusă este diferită de cea atribuită contului, atunci afișează un mesaj specific, oferă opțiunea de recuperare a parolei pe adresa de email și cere introducerea parolei corecte

F2.8 Permite schimbarea parolei sau a adresei de email

F2.9 Memorează noua parolă sau adresă de email dacă acestea au fost schimbate

F2.10 Permite vizualizarea evenimentelor

F2.11 Permite selectarea preferințelor

F2.12 Permite rezervarea biletelor

F3. Gestionare evenimente

F3.1 Solicită parola de administrator

F3.2 Preia și verifică corectitudinea parolei introduse

F3.3 În cazul în care parola introdusă este greșită afișează un mesaj specific și nu permite accesul în sistem

F3.4 Permite adăugarea, modificarea sau eliminarea categoriilor

F3.5 Permite adăugarea, modificarea sau eliminarea evenimentelor

F3.6 Solicită informațiile unui nou eveniment

F3.7 Memorează evenimentul împreună cu informațiile acestuia

F4. Vizualizare evenimente

F4.1 Afișează evenimentele disponibile

F4.2 Permite specificarea criteriilor de căutare a evenimentelor (categorie, un anumit eveniment, data la care are loc)

F4.3 Afișează evenimentele ce îndeplinesc criteriul sau criteriile introduse de către utilizator

F4.4 Permite selectarea unui eveniment pentru mai multe detalii

F4.5 Afișează informații despre un eveniment

F5. Selectare preferințe

F5.1 Permite selectarea unei categorii de evenimente după unul sau mai multe criterii (localitate, dată, tip de eveniment, etc)

F5.2 Permite eliminarea unei preferințe anterioare

F5.3 Memorează setul de preferințe

F6. Notificare utilizatori

F6.1 Verifică preferințele utilizatorilor

F6.2 Trimite un email cu informațiile evenimentului nou introdus utilizatorilor ce au optat pentru acea categorie de evenimente sau acel eveniment

F7. Rezervare bilete

F7.1 Permite introducerea datelor despre rezervare

F7.2 Afișează categoriile de locuri disponibile și prețul lor

F7.3 Permite alegerea unuia sau mai multor locuri

F7.4 Afișează informații despre rezervare

F7.5 Cere confirmarea rezervării

F7.6 Memorează rezervarea

F7.7 Oferă un bilet electronic

F7.8 Realizează imprimarea biletului

Cerințe nefuncționale

CN1. Aplicația va fi implementată folosind limbajul Java.

CN2. Aplicația va folosi o bază de date MySQL.

CN3. Aplicația va da dovadă de robustețe. Ea va verifica datele introduse de utilizator și va continua dar ulterior validării acestora. În caz contrar, aplicația va notifica utilizatorul cerând mai apoi introducerea datelor corecte.

Modelul funcțional

Modelul funcțional este o reprezentare structurată text și/sau semi-formal a funcțiilor sistemului. Acest lucru se realizează prin definirea cazurilor de utilizare și asocierea lor a unor diagrame UML specifice din care să reiasă descrierea comportamentului sistemului software dezvoltat.

Cazul de utilizare este un element UML de modelare ce descrie comportamentul sistemului pentru a realiza una sau mai multe funcționalități ale sistemului cu scopul de a furniza un beneficiu unui actor sau unor actori software.

Un caz de utilizare poate fi descris informal conform unui șablon ce conține: denumirea și descrierea cazului, actorii software ce interacționează cu sistemul, starea sistemului înainte și după execuția cazului de utilizare, precum și fluxul de activități ale cazului ce reprezintă pașii urmați de către sistem și eventual actorul sau actorii software care interacționează cu sistemul pentru realizarea beneficiul dorit. Acest flux este constituit dintr-un flux principal la care pot fi asociate unul sau mai multe fluxuri alternative, acoperind astfel întreaga funcționalitate pe durata cazului.

Cazul de utilizare: Creare cont

Descrie: Interacțiunea dintre un utilizator și sistem în vederea creării unui cont

Actori: Utilizator

Eveniment: Utilizatorul dorește crearea unui cont

Precondiții: Legătura dintre client și server este activă

Post condiții: Sistemul a memorat un cont nou pe care utilizatorul îl poate folosi pentru a se autentifica

Flux Principal:

Flux alternativ:

[A1] Numele de utilizator este deja folosit

Sistemul afișează un mesaj

Sistemul solicită un nume de utilizator diferit

Fluxul continuă de la pasul 3 din fluxul principal

Cazul de utilizare: Autentificare în sistem

Descrie: Interacțiunea dintre utilizator și sistem în vederea autentificării în sistem

Actori: Utilizator

Eveniment: Utilizatorul dorește să se autentifice în sistem folosind un cont existent

Precondiții: Legătura dintre client și server este activă, iar sistemul a memorat anterior un cont

Post condiții: Sistemul a oferit acces utilizatorului la funcționalitățile disponibile

Flux principal:

Flux alternativ:

[A1] Numele de utilizator nu este asociat unui cont existent

Sistemul afișează un mesaj specific

Sistemul oferă opțiunea de a crea un cont nou cu datele introduse

Sistemul solicită un nume de utilizator și o parolă asociate unui cont existent

Fluxul continuă de la pasul 3 din fluxul principal

[A2] Numele de utilizator este asociat unui cont existent dar parola este greșită

Sistemul afișează un mesaj specific

Sistemul oferă opțiunea de a recupera parola curentă pe adresa de email

Sistemul solicită parola corectă asociată contului introdus

Fluxul continuă de la pasul 3 din fluxul principal

Cazul de utilizare: Adăugare eveniment

Descrie: Interacțiunea dintre administrator și sistem în vederea adăugării unui eveniment nou

Actori: Administrator

Eveniment: Administratorul dorește să introducă un eveniment nou în sistem

Precondiții: Administratorul s-a autentificat la calculatorul pe care rulează terminalul server

Post condiții: Evenimentul a fost salvat și este acum disponibil pentru toți utilizatorii

Flux principal:

Flux alternativ:

[A1] Unele date nu sunt valide

Sistemul afișează un mesaj specific

Sistemul solicită corectarea informațiilor

Fluxul continuă de a pasul 3 din fluxul principal

Cazul de utilizare: Vizualizare evenimente

Descrie: Interacțiunea dintre utilizator și sistem cu scopul de a vizualiza evenimentele disponibile și detaliile acestora

Actori: Utilizator

Eveniment: Un utilizator dorește să afle mai multe detalii cu privire la un anumit eveniment

Precondiții: Legătura dintre client și server este activă, utilizatorul s-a autentificat anterior, iar administratorul a introdus în sistem evenimentul în cauză

Post condiții: Sistemul îi oferă informații utilizatorului cu privire la evenimentul selectat și opțiunea de a rezerva un bilet.

Flux principal:

Cazul de utilizare: Selectare preferințe

Descrie: Interacțiunea dintre utilizator și sistem în vederea abonării la serviciul de notificări

Actori: Utilizator

Eveniment: Un utilizator dorește să își modifice preferințele categoriile de evenimente pentru care este notificat de către sistem prin email

Precondiții: Legătura dintre client și server este activă iar utilizatorul s-a autentificat anterior

Post condiții: Sistemul a memorat noile preferințe ale utilizatorului

Flux principal:

Cazul de utilizare: Notificare utilizatori

Descrie: Procesul automat al serverului de notificare a utilizatorilor

Actori:

Precondiții: Sistemul a memorat datele unui eveniment nou introdus

Post condiții: Sistemul a notificat prin email toți utilizatorii interesați

Flux principal:

Flux alternativ:

[A1] Nu mai sunt utilizatori

Fluxul principal se oprește

Cazul de utilizare: Rezervare bilete

Descrie: Interacțiunea dintre utilizator și sistem în vederea rezervării unuia sau a mai multor bilete

Actori: Utilizator

Eveniment: Un utilizator dorește să își rezerve unul sau mai multe locuri la un eveniment

Precondiții: Legătura dintre client și server este activă, utilizatorul s-a autentificat anterior, iar sistemul a memorat evenimentul în cauză

Post condiții: Sistemul a furnizat și a memorat un bilet asociat unei rezervări

Flux principal:

Flux alternativ:

[A1] Utilizatorul refuză rezervarea

Fluxul principal oprește

Diagrama cazurilor de utilizare

Un alt mod de a descrie funcționalitatea sistemului este prin intermediul diagramei cazurilor de utilizare. Ea descrie vizual funcționalitatea sistemului arătând actorii software, cazurile de utilizare software și relațiile dintre aceste elemente de modelare.

Aplicarea acestei diagrame poate avea loc în 2 moduri.

Într-o etapă, diagrama este folosită pentru a modela contextul sistemului. Aceasta implică definirea frontierei sistemului prin intermediul unei diferențieri a task-urilor realizate de acesta și celor îndeplinite de actori. Totodată această etapă mai presupune și găsirea actorilor ce interacționează cu sistemul.

În cealaltă etapă, diagrama este folosită pentru a modela cerințele unui sistem. În acest caz are loc specificarea a ceea ce trebuie să facă sistemul independent de modalitatea de realizare.

În stabilirea diagramei au loc o serie de pași după cum urmează:

Se stabilește contextul sistemului prin intermediul identificării actorilor din exteriorul său;

Se factorizează comportamentul pe care sistemul îl cere sau îl așteaptă de la fiecare dintre acești actori sub numele de cazuri de utilizare;

Se ia în considerare comportamentul comun și se identifică pe baza lui noi cazuri de utilizare ce extind fluxuri de evenimente principale;

Se modelează diagrama cazurilor de utilizare din informațiile selectate: actori, cazuri de utilizare și relațiile dintre acestea;

În următorul tabel sunt explicate conceptele diagramei cazurilor de utilizare.

În continuare prezentăm diagrama cazurilor de utilizare a sistemului Event-Hub.

Diagrame de secvențe de sistem

Scenariile cazurilor de utilizare sunt ilustrate prin intermediul diagramelor de secvențe. Acestea descriu obiectele și interacțiunile dintre ele din punct de vedere temporal (sistem și actori software) de-a lungul unui scenariu.

Obiectele ce apar în diagrama de secvență au clasele reprezentate în diagrama de clase, împreună cu relațiile ce au fost definite. Mesajele corespund operațiilor de comunicare ale obiectelor și nu pot exista fără operația corespunzătoare. Ele reprezintă apeluri ale acestor operații ce au fost descrise la nivelul claselor.

Diagramele de secvențe împreună cu diagramele de comunicare constituie categoria diagramelor de interacțiune. Specificul lor este acela de a evidenția mesajele trimise între obiecte. Prin intermediul diagramelor de comunicare se descrie aspectul structural al colaborării obiectelor în timp ce diagramele de secvențe pun accentul pe aspectul temporal al interacțiunii dintre ele.

O diagramă a secvențelor de sistem este o diagramă de secvențe specializată pe descrierea interacțiunilor prin mesaje dintre actori software și sistemul software. Mulțimea mesajelor este structurată într-un flux de informații direcționat între obiectele expeditor și destinatar și pot fi trimise chiar aceluiași obiect.

În următorul tabel sunt explicate conceptele diagramei de secvențe de sistem.

În continuare prezentăm diagramele secvențe de sistem ale cazurilor de utilizare ale sistemului Event-Hub.

Diagrama cazului de utilizare: Creare cont

Diagrama cazului de utilizare: Autentificare în sistem

Diagrama cazului de utilizare: Adăugare eveniment

Diagrama cazului de utilizare: Vizualizare eveniment

Diagrama cazului de utilizare: Selectare preferințe

Diagrama cazului de utilizare: Rezervare bilet

Modelul domeniului

Modelul domeniului este un model conceptual al domeniului problemei ce identifică tipurile de informații persistente ale organizației sau întreprinderii. El conține obiectele business sub formă de concepte cheie, precum și rolurile, atributele și relațiile lor.

Diagrama de clase

Modelul domeniului oferă o vizualizare structurată asupra conceptelor cheie prin intermediul diagramei de clase. Crearea acesteia se bazează pe o serie de concepte.

În următorul tabel sunt explicate conceptele diagramei de clase.

Pentru a crea diagrama de clase trebuie mai întâi să se identifice substantivele din definiția problemei, descrierea cazurilor de utilizare, a documentației și a proceselor business. Acestea sunt apoi analizate și transformate în elemente specifice (clase, obiecte, atribute sau valori) din care se elimină cele care aparțin la domeniul soluției.

În următorul tabel prezentăm conceptele care aparțin domeniului problemei ce va fi rezolvată de sistemul Event-Hub.

În urma identificării conceptelor se poate crea diagrama de clase. Scopul modelului domeniului este acela de a identifica informațiile semnificative, motiv pentru care clasele nu vor conține operații. Conform procesului de dezvoltare a oricărui sistem software, identificarea lor se realizează în faza de proiectare a sistemului, în capitolul următor.

În continuare prezentăm diagrama de clase a sistemului Event-Hub.

Proiectarea și implementarea aplicației

Arhitecturi software

Implementarea aplicației este precedată de realizarea unei soluții conceptuale ce presupune construirea unei arhitecturi software a sistemului sub forma unei descrieri a componentelor constituente precum și a legăturilor dintre acestea ce duc la coordonarea acțiunilor în cadrul sistemului software.

Această etapă poartă numele de proiectare și are drept scop asigurarea îndeplinirii cerințelor identificate și descrise anterior în faza de analiză. Prin intermediul ei se asigură obținerea unui calități sporite a sistemului prin rezolvarea deciziilor anterior implementării și apariția unei oportunități de a refolosi componente realizate anterior ce aparțin procesului de dezvoltarea a unor sisteme similare. Aceste componente pot fi orice de la module, obiecte și servicii a căror funcționalitate a fost implementată separat de logica de ansamblu a întregului sistem.

Realizarea unei arhitecturi software anterior implementării joacă un rol important în procesul de dezvoltare al aplicațiilor. Modularizarea componentelor duce la crearea unei nivel de abstractizare ce permite ușurința în înțelegere a unui sistem complex. Totodată separarea funcționalității pe componente duce la furnizarea unor dimensiuni ce permit evoluția sistemului software datorită diferențierii clare de mecanismele de comunicare dintre acestea. Astfel componentele software, modelele de proiectare și/sau framework-urile pot fi reutilizate în asamblarea unor componente software noi cu funcționalități extinse.

Stilul arhitectural Client-Server

De regulă o aplicație proiectată conform stilului arhitectural client-server este extinsă pe mai multe calculatoare, dar aceasta poate fi rulată și pe același calculator. Atât clientul cât și serverul reprezintă procese independente care comunică prin intermediul rețelei, fapt ce duce la cooperarea în privința activității de elaborare a datelor.

Avantajele principale ale acestui stil sunt că un număr sporit de clienți pot trimite simultan cereri de servicii serverului care are posibilitatea de a le răspunde tuturor precum și independența creată dintre clienți și server ce facilitează modificarea individuală. Astfel, modificarea unei singure entități nu le afectează pe celelalte. Totodată acest stil permite un control eficient al resurselor aflate pe server.

Principalul dezavantaj este adus de crearea unu trafic intens de date în rețea ceea ce poate conduce la reducerea timpului de răspuns din partea serverului.

Stilul arhitectural pe straturi

Stilul arhitectural pe straturi presupune organizarea funcționalităților oferite de sistemul software pe mai multe nivele. Scopul acestei stratificări este acela ca un anumit nivel să poată furniza servicii unui strat superior în timp ce acționează drept client pentru un strat inferior. Regularea interacțiunilor dintre componente se face pe bază de protocoale și poate presupune o serie de constrângeri. Deși nu este obligatoriu, de regulă aceste interacțiuni sunt limitate la avea loc doar între componentele ale căror straturi sunt adiacente. Această constrângere face diferența dintre arhitecturile închise și cele deschise. Într-o arhitectură deschisă, toate componentele sunt libere să comunice cu orice componentă indiferent de stratul de care aparține, în timp ce prezența constrângerii impune ca arhitectura acelui sistem să fie închisă.

Acest stil arhitectural aduce cu el o multitudine de avantaje. Datorită abstractizării aduse de organizarea pe nivele, procesul de proiectare conduce la simplificarea unei probleme complexe într-o serie de pași incrementali. Fiecare strat poate avea versiuni diferite de implementare, iar dacă acestea nu modifică interfețele folosite pentru a comunica cu celelalte componente atunci ele pot fi înlocuite fără a fi necesare alte modificări.

Dezavantajul îl reprezintă dificultatea de a structura funcționalitățile unui sistem software pe nivele, în schimb abilitatea de a reutiliza implementări anterioare ale unui nivel cu scop identic face ca structurarea într-o asemenea manieră să fi mai convenabilă în rezolvarea problemelor complexe în comparație cu un stil arhitectural non ierarhic.

Stilul arhitectural Model-View-Controller

Responsabilitățile unui sistem software pot fi împărțite pe anumite componente iar acest stil arhitectural presupune întocmai acest lucru. În funcție de rolul îndeplinit de un anumit obiect, acesta aparține unuia din cele 3 categorii specifice stilului după cum sunt expuse mai jos:

Model: Conform acestei categorii, obiectele reprezintă entități ce aparțin domeniului sistemului. Acestea respectă într-o anume măsură obiectele prezente în modelul de domeniu dar sunt limitate doar la acelea. Un obiect care aparține acestui acestei categorii poartă numele de obiect entitate.

View: În această categorie intră toate obiectele care au ca rol să interacționeze în mod direct cu unul dintre actorii sistemului. Aici se numără atât ferestrele și formularele, dar pot fi și de alt tip. Un obiect care aparține acestui acestei categorii poartă numele de obiect de frontieră.

Controller: Obiectele prezente în această categorie sunt însărcinate cu fluxul logic al aplicației și gestionează toate evenimentele produse de actori prin intermediul obiectelor de frontieră. Un obiect care aparține acestei categorii poartă numele de obiect de control.

Arhitectura software a unui sistem poate fi construită urmând mai multe stiluri arhitecturale, programatorul având posibilitatea de a le combina.

Sistemul Event-Hub a fost proiectat folosind stilurile arhitecturale enumerate anterior și respectă modelele de proiectare ce vor fi expuse în continuare.

Modele de proiectare

Unele modele sunt folosite frecvent în procesul de dezvoltare al unui sistem software. Astfel de modele se numesc modele de proiectare și conțin recomandări în ceea ce privește modul de alocare al responsabilităților într-o aplicație orientată pe obiecte astfel încât să fie rezolvate anumite probleme de proiectare.

GRASP (General Responsibility Assignment Software Patterns) este un set de astfel de modele ce servește drept ajutor în proiectarea sistemelor. Diferitele principii de proiectare fundamentale utilizate în GRASP sunt: Controller, Creator, Indirection, Information Expert, High Cohesion, Low Coupling, Polymorphism, Protected Variations și Pure Fabrication. Fiecare dintre acestea abordează un anumit tip de problemă comună în procesul de proiectare al unui sistem software.

Controller

Un obiect controller are responsabilitatea de a gestiona totalitatea evenimentelor de sistem create de un actor software prin intermediul interacțiunii cu obiectele de frontieră precum ferestrele și formulare. Rolul acestui obiect este acela de a decupla sursa evenimentelor externe de obiectul care gestionează acele evenimente. Un criteriu este acela ca fiecare caz de utilizare în parte să aibă un obiect de tip controller sau, în funcție de caz, mai multe, care să gestioneze fluxul și să încapsuleze informații cu privire la starea curentă a acelui caz de utilizare. Interfața controllerului are metode corespunzătoare unei anumite acțiuni din partea actorului și coordonează activitatea el însuși sau prin intermediul unor alte obiecte.

Creator

Un obiect creator reprezintă un obiect care are drept responsabilitate crearea de obiecte în cadrul sistemului. Acest concept abordează o problemă de o importanță sporită în programarea unui sistem orientat spre obiecte cu privire la clasa cu această responsabilitate. O clasă este considerată creator al unui obiect de tip dacă conține sau agregă instanțe de acel tip, gestionează instanțe de acel tip, folosește intensiv instanțe de acel tip și are informațiile necesare pentru a inițializa un obiect de tipul respectiv.

Information Expert

Acest principiu ajută la determinarea alocări potrivite a unei noi responsabilități unei clase. Această responsabilitate poate fi o metodă, un câmp sau un calcul iar modul prin care se alocă este prin analizarea informațiilor necesare pentru îndeplinirea acelei responsabilități, iar apoi determinarea locației acelor informații. În general, noua responsabilitate se atribuie întocmai clasei care conține informațiile necesare.

High Cohesion

Conform acestui principiu, alocarea unei responsabilități noi trebuie făcute clasei care are funcționalități asemănătoare sau înspre același scop astfel încât ele să fie strâns legate între ele. Aceasta se numește coeziune înaltă și ajută la o mai bună înțelegere a acelui obiect și sporirea ușurinței în întreținere și reutilizare. Practic vorbind, ceea ce înseamnă este că responsabilitățile unei clase trebuie să fie concentrate în jurul aceleiași noțiuni. Astfel acea clasă încapsulează un set de responsabilități înrudite.

Low Coupling

O altă modalitate de a spori potențialul unei clase de a fi reutilizată pe viitor precum și a o face mai ușor de înțeles este prin intermediul cuplării slabe. Cuplarea este un concept care reprezintă gradul de dependență dintre clase, iar acesta trebuie să fie cât mai mic. Totodată el mai semnifică și gradul de cunoștințe pe care o clasă o are despre o alta. Asigurarea unei cuplări slabe duce la un impact scăzut în cadrul sistemului în ceea ce privește modificările aduse unei clase.

Indirection

Se recomandă pentru a asigura o cuplare slabă să se împartă responsabilitățile de mediere dintre două clase unui obiect intermediar care să gestioneze interacțiunile dintre acestea. Un exemplu al unei astfel de utilizări este în cadrul stilului arhitectural Model-View-Controller unde se folosesc clasele de tip Controller pentru a decupla interacțiunile dintre obiectele de tip Model și obiectele de tip View. Această practică duce la un potențial sporit ca cele două clase să fie refolosite într-un proiect ulterior și în concluzie sporește eficacitatea întregului proces de proiectare a unui sistem software.

Polymorphism

Principiul denumit polimorfism recomandă implementarea unor comportamente variate ale claselor prin intermediul unor interfețe. Astfel clasele vor putea fi reutilizate ulterior, iar dacă va fi necesar un comportament diferit se poate implementa doar noul comportament.

Protected Variations

O altă problemă ce poate apărea în procesul de dezvoltare este ca la implementarea unei anumite variații întreg sistemul să ajungă să fie afectat și să necesite o revizuire masivă. Acest lucru poate fi evitat prin încapsularea variațiilor viitoare într-o nouă clasă astfel încât sistemul să nu mai necesite acele schimbări.

Pure Fabrication

Aplicarea succesivă a modelului Information Expert poate duce la o încălcare a principiului de coeziune ridicată și cuplare slabă de către sistem. Această situație se rezolvă prin crearea unei clase artificiale care nu face parte din domeniul problemei în care se implementează un set de responsabilități aparținând anterior unei clase cu coeziune slabă.

Diagrame de interacțiuni

Diagramele de interacțiuni sunt asemănătoare diagramelor de secvențe de sistem în sensul că ilustrează comunicarea dintre obiecte în cadrul fluxului de informație prin intermediul unor mesaje sub formă de semnal sau apel și care pot fi acompaniate de parametri. Fiecare obiect are o linie de viață și una sau mai multe activări care indică perioada de execuție a unor operații, fie el însuși, fie prin intermediul altor obiecte.

Diagramele de interacțiune sunt împărțite în două categorii: diagrame de secvențe și diagrame de comunicare (colaborare).

Diferența dintre diagramele de secvențe și diagramele de secvențe de sistem este aceea că cele din a doua categoroe ilustrează comunicarea dintre un actor și sistemul la general în contextul unui caz de utilizare în timp ce diagramele de secvențe evocă obiecte ale acelui caz și arată interacțiunile lor pentru a descrie colaborarea acelui caz.

În continuare prezentăm diagramele de interacțiuni ale sistemului Event-Hub.

Diagrama de interacțiuni a cazului de utilizare: Creare Cont

Diagrama de interacțiuni a cazului de utilizare: Autentificare în sistem

Diagrama de interacțiuni a cazului de utilizare: Adăugare Eveniment

Diagrama de interacțiuni a cazului de utilizare: Vizualizare eveniment

Diagrama de interacțiuni a cazului de utilizare: Selectare preferințe

Diagrama de interacțiuni a cazului de utilizare: Rezervare bilet

Diagrame de clase de proiectare

Diagramele de clase de proiectare aparțin modelului de proiectare. Ele reprezintă descrieri ale claselor unui sistem software și ilustrează atributele și operațiile fiecăreia, precum și interfețele, dependențele și asociațiile dintre ele.

Diferența dintre diagramele de clase ale domeniilor problemelor și diagramele de clase de proiectare este aceea că cele dintâi reprezintă concepte ale lumii reale și a domeniului problemei în timp ce diagramele de clase de proiectare reprezintă obiecte software ale proiectării și implementării.

În continuare prezentăm diagramele de clase de proiectare ale sistemului Event-Hub.

Diagrama de clase de proiectare a cazului de utilizare: Creare Cont

Diagrama de clase de proiectare a cazului de utilizare: Autentificare în sistem

Diagrama de clase de proiectare a cazului de utilizare: Adăugare eveniment

Diagrama de clase de proiectare a cazului de utilizare: Vizualizare eveniment

Diagrama de clase de proiectare a cazului de utilizare: Selectare preferințe

Diagrama de clase de proiectare a cazului de utilizare: Rezervare bilet

Proiectarea bazei de date

În continuare prezentăm structura bazei de date a sistemului Event-Hub.

În continuare prezentăm codul responsabil cu generarea bazei de date.

CREATE PROCEDURE creaza_tabele()

BEGIN

CREATE TABLE `Conturi`(

IdCont int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,

Nume varchar(30) NOT NULL,

Prenume varchar (30) NOT NULL,

Email varchar (100) NOT NULL,

Parola varchar (100) NOT NULL,

Admin boolean NOT NULL DEFAULT FALSE,

CONSTRAINT conturi_rol UNIQUE (Email, Admin)

);

CREATE TABLE `Judete`(

IdJudet int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,

Judet varchar(30) NOT NULL

);

CREATE TABLE `Localitati`(

IdLocalitate int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,

IdJudet int unsigned NOT NULL,

Localitate varchar(30) NOT NULL,

FOREIGN KEY (`IdJudet`) REFERENCES `Judete`(`IdJudet`) ON UPDATE CASCADE ON DELETE CASCADE

);

CREATE TABLE `CategoriiEvenimente`(

IdCategorie int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,

Categorie varchar(30) NOT NULL UNIQUE

);

CREATE TABLE `Preferinte`(

IdPreferinta int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,

IdCont int unsigned NOT NULL,

IdCategorie int unsigned NOT NULL,

Continut varchar(500),

DataInceput timestamp NOT NULL DEFAULT current_timestamp,

DataSfarsit timestamp NOT NULL DEFAULT current_timestamp,

OriceData boolean NOT NULL DEFAULT TRUE,

IdLocalitate int unsigned NOT NULL,

FOREIGN KEY (`IdCont`) REFERENCES `Conturi`(`IdCont`) ON UPDATE CASCADE ON DELETE CASCADE,

FOREIGN KEY (`IdLocalitate`) REFERENCES `Localitati`(`IdLocalitate`) ON UPDATE CASCADE ON DELETE CASCADE,

FOREIGN KEY (`IdCategorie`) REFERENCES `CategoriiEvenimente`(`IdCategorie`) ON UPDATE CASCADE ON DELETE CASCADE

);

CREATE TABLE `Evenimente`(

IdEveniment int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,

IdCategorie int unsigned NOT NULL,

Denumire varchar(50) NOT NULL,

Descriere varchar (500) NOT NULL,

DataEveniment timestamp NOT NULL DEFAULT current_timestamp,

IdLocalitate int unsigned NOT NULL,

FOREIGN KEY (`IdCategorie`) REFERENCES `CategoriiEvenimente`(`IdCategorie`) ON UPDATE CASCADE ON DELETE CASCADE,

FOREIGN KEY (`IdLocalitate`) REFERENCES `Localitati`(`IdLocalitate`) ON UPDATE CASCADE ON DELETE CASCADE

);

CREATE TABLE `CategoriiLocuri`(

IdCategorieLocuri int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,

IdEveniment int unsigned NOT NULL,

Denumire varchar(30) NOT NULL,

Pret float NOT NULL,

NrLocuriDisponibile int unsigned NOT NULL,

LocuriPeScaune boolean DEFAULT FALSE,

PrimulRand int unsigned,

UltimulRand int unsigned,

PrimulScaun int unsigned,

UltimulScaun int unsigned,

FOREIGN KEY (`IdEveniment`) REFERENCES `Evenimente`(`IdEveniment`) ON UPDATE CASCADE ON DELETE CASCADE

);

CREATE TABLE `Rezervari`(

IdRezervare int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,

IDCont int unsigned NOT NULL,

FOREIGN KEY (`IdCont`) REFERENCES `Conturi`(`IdCont`) ON UPDATE CASCADE ON DELETE CASCADE

);

CREATE TABLE `LocuriRezervate`(

IdLoc int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,

IdCategorieLocuri int unsigned NOT NULL,

IdRezervare int unsigned NOT NULL,

Rand int unsigned,

Scaun int unsigned,

FOREIGN KEY (`IdCategorieLocuri`) REFERENCES `CategoriiLocuri`(`IdCategorieLocuri`) ON UPDATE CASCADE ON DELETE CASCADE,

FOREIGN KEY (`IdRezervare`) REFERENCES `Rezervari`(`IdRezervare`) ON UPDATE CASCADE ON DELETE CASCADE

);

ALTER TABLE `Conturi` AUTO_INCREMENT = 1;

ALTER TABLE `Judete` AUTO_INCREMENT = 1;

ALTER TABLE `Localitati` AUTO_INCREMENT = 1;

ALTER TABLE `CategoriiEvenimente` AUTO_INCREMENT = 1;

ALTER TABLE `Preferinte` AUTO_INCREMENT = 1;

ALTER TABLE `Evenimente` AUTO_INCREMENT = 1;

ALTER TABLE `CategoriiLocuri` AUTO_INCREMENT = 1;

ALTER TABLE `Rezervari` AUTO_INCREMENT = 1;

ALTER TABLE `LocuriRezervate` AUTO_INCREMENT = 1;

END

Implementarea aplicației

Implementarea sistemul Event-Hub a fost realizată în două pachete separate, primul pentru client și cel de al doilea pentru server. Clasele precum Eveniment, Bilet și Rezervare fac parte din pachetul server și realizează interfața Serializable astfel încât să poată fi transferate prin intermediul rețelei și interpretate corect la client.

În continuare vom prezenta secvențe de cod cu roluri specifice din implementare pentru clase aparținând celor două pachete.

Conexiunea dintre Client și Server

Conexiunea între cele două părți ale sistemului a fost realizată prin intermediul conceptului de Socket. La pornirea Serverului se creează un nou fir de execuție pentru obiectul de tip ControllerServer astfel încât execuția acestuia să nu afecteze interfața grafică. Acest obiect apoi creează câte un nou fir de execuție pentru fiecare conexiune acceptată.

În continuare prezentăm codul clasei ControllerServer.

public class ControllerServer implements Runnable{

private final int port=123;

private final String delimitator="#delimitator#";

private static final ControllerServer instance=new ControllerServer();

private ControllerServer(){};

public static ControllerServer getInstance(){

return instance;

}

public String getDelimitator(){

return delimitator;

}

@Override

public void run(){

try {

ServerSocket server=new ServerSocket(port);

while(true){

new ServerThread(server.accept()).run();

}

} catch(Exception e){

System.out.println(e.getMessage());

}

}

}

Așa cum se poate observa din codul prezentat anterior, algoritmul asociat unui singur fir de execuție atribuit unui anumit client la un moment dat este implementat în clasa ServerThread. Aceasta implementează o metodă denumită “interpreteaza” cu rolul de a transmite mesajul primit obiectului destinatar de pe Server și întoarcerii răspunsului aferent.

În continuare prezentăm codul clasei ServerThread.

public class ServerThread extends Thread{

String d=MVC.getInstance().CtrlS().getDelimitator();

Socket socket;

ObjectInputStream ois;

public ServerThread(Socket socket){

this.socket=socket;

}

public void run(){

System.out.println("\nConexiune initiata! "+new Date());

try {

ObjectOutputStream oos=new ObjectOutputStream(socket.getOutputStream());

ois=new ObjectInputStream(socket.getInputStream());

oos.writeObject(interpreteaza(ois.readObject()));

ois.close();

oos.close();

socket.close();

} catch(Exception e){

System.out.println(e.getMessage());

}

}

private Object interpreteaza(Object continut){

Object raspuns=null;

String[] mesaj=((String)continut).split(d);

for(int i=0;i<mesaj.length;i++){

System.out.println("["+mesaj[i]+"]");

}

if(mesaj[0].equals("MngrC")){

if(mesaj[1].equals("verificaUnicitate")){

raspuns=MVC.getInstance().MngrC().verificaUnicitate(mesaj[2]);

} else if(mesaj[1].equals("memoreazaCont")){

try {

raspuns=MVC.getInstance().MngrC().memoreazaCont((Utilizator)ois.readObject());

} catch(Exception e){

System.out.println(e.getMessage());

}

} else if(mesaj[1].equals("verificaCont")){

raspuns=MVC.getInstance().MngrC().verificaCont(mesaj[2],mesaj[3]);

}

} else if(mesaj[0].equals("MngrE")){

if(mesaj[1].equals("lista")){

raspuns=MVC.getInstance().MngrE().lista();

} else if(mesaj[1].equals("filtrare")){

raspuns=MVC.getInstance().MngrE().filtrare(mesaj[2],Integer.parseInt(mesaj[3]),mesaj[4],mesaj[5],mesaj[6],Integer.parseInt(mesaj[7]));

} else if(mesaj[1].equals("eveniment")){

raspuns=MVC.getInstance().MngrE().eveniment(Integer.parseInt(mesaj[2]));

}

} else if(mesaj[0].equals("MngrP")){

if(mesaj[1].equals("judete")){

raspuns=MVC.getInstance().MngrP().judete();

} else if(mesaj[1].equals("localitati")){

raspuns=MVC.getInstance().MngrP().localitati();

} else if(mesaj[1].equals("categorii")){

raspuns=MVC.getInstance().MngrP().categorii();

} else if(mesaj[1].equals("listaPreferinte")){

try {

raspuns=MVC.getInstance().MngrP().listaPreferinte((Utilizator)ois.readObject());

} catch(Exception e){

System.out.println(e.getMessage());

}

} else if(mesaj[1].equals("memoreaza")){

raspuns=MVC.getInstance().MngrP().memoreaza(mesaj[2], mesaj[3], mesaj[4], mesaj[5], mesaj[6], mesaj[7], mesaj[8]);

} else if(mesaj[1].equals("sterge")){

raspuns=MVC.getInstance().MngrP().sterge(Integer.parseInt(mesaj[2]));

}

} else if(mesaj[0].equals("MngrR")){

if(mesaj[1].equals("rezervari")){

raspuns=MVC.getInstance().MngrR().rezervari(Integer.parseInt(mesaj[2]));

} else if(mesaj[1].equals("memoreaza")){

try {

raspuns=MVC.getInstance().MngrR().memoreaza((Rezervare)ois.readObject());

} catch(Exception e){

System.out.println(e.getMessage());

}

}

}

return raspuns;

}

}

În ceea ce privește codul prezent în pachetul Client, acesta implementează o clasă încredințată cu rolul de a realiza conexiunea la Server, de a trimite un mesaj împreună cu parametrii aferenți și de a asculta pentru un răspuns.

În continuare prezentăm codul clasei ControllerClient.

public class ControllerClient {

private String host="";

private final int port=123;

private final String delimitator="#delimitator#";

private Object obiect;

public static ControllerClient instance=new ControllerClient();

private ControllerClient(){};

public static ControllerClient getInstance(){

return instance;

}

public String getDelimitator(){

return delimitator;

}

public Object trimite(Object continut){

return trimite(continut,false);

}

public Object trimite(Object continut, Object obiect){

this.obiect=obiect;

return trimite(continut,true);

}

public Object trimite(Object continut, boolean extra){

if(host.isEmpty()){

host=JOptionPane.showInputDialog("Introduceti un IP pentru host:");

}

Object raspuns=null;

try {

Socket socket=new Socket(host,port);

ObjectInputStream ois=new ObjectInputStream(socket.getInputStream());

ObjectOutputStream oos=new ObjectOutputStream(socket.getOutputStream());

oos.writeObject(continut);

if(extra){

oos.writeObject(obiect);

}

raspuns=ois.readObject();

ois.close();

oos.close();

socket.close();

} catch(Exception e){

System.out.println(e.getMessage());

JOptionPane.showMessageDialog(null,"A avut loc o eroare la conectarea cu serverul!","Eroare",JOptionPane.ERROR_MESSAGE);

}

return raspuns;

}

}

Conexiunea la baza de date

Conexiunea dintre Server și baza de date a fost implementată într-o clasă de tip Singleton astfel încât să se poată preveni atât citirea și scrierea eronată cât și crearea unui trafic intens de date între serverul aplicației și serverul de baze de date în cazul în care acestea se află pe dispozitive diferite. Soluția dată în acest material utilizează o baza de date locală.

Totodată clasa Conexiune implementează metodele “interogheaza” și “actualizeaza” care primesc câte un obiect de tip String conținând cererea aferentă redactată în SQL.

În continuare prezentăm codul clasei Conexiune.

public class Conexiune {

private static Conexiune instance=new Conexiune();

private static final String DB_URL="jdbc:mysql://localhost:3306/eventhub";

private static final String USER="eventhubadmin";

private static final String PASS="administrator2015";

private static Connection connection;

private Conexiune(){

try {

connection=DriverManager.getConnection(DB_URL,USER,PASS);

} catch(Exception e){

System.out.println(e.getMessage());

JOptionPane.showMessageDialog(null,"A avut loc o eroare la conectarea cu baza de date!", "Eroare", JOptionPane.ERROR_MESSAGE);

}

};

public static Conexiune getInstanta(){

return instance;

}

public ResultSet interogheaza(String interogare){

ResultSet raspuns=null;

try {

Statement statement=connection.createStatement();

raspuns=statement.executeQuery(interogare);

} catch(Exception e){

System.out.println(e.getMessage());

JOptionPane.showMessageDialog(null,"A avut loc o eroare la interogarea bazei de date!", "Eroare", JOptionPane.ERROR_MESSAGE);

}

return raspuns;

}

public boolean actualizeaza(String actualizare){

try{

Statement statement=connection.createStatement();

if(statement.executeUpdate(actualizare)==1){

return true;

}

} catch(Exception e){

System.out.println(e.getMessage());

JOptionPane.showMessageDialog(null,"A avut loc o eroare la actualizarea bazei de date!", "Eroare", JOptionPane.ERROR_MESSAGE);

}

return false;

}

}

Creare cont și Autentificare în sistem

Crearea de cont și autentificarea în sistem se realizează prin intermediul Controllerelor aferente pe partea de client și a Managerului de Conturi pe partea de server. La pornirea aplicației, utilizatorul este întâmpinat cu opțiunea de a continua cu unul dintre cele 2 cazuri.

În continuare prezentăm fereastra de pornire a sistemului Event-Hub pentru clienți.

Ulterior selectării opțiunii dorite, acesta este întâmpinat cu fereastra aferentă care după introducerea datelor trimite cererea Controllerului asociat cazului de utilizare. Acesta comunică cu Serverul prin metoda expusă anterior către Managerul de Conturi care în funcție de caz întoarce un răspuns ce permite sau nu continuarea fluxului.

În continuare prezentăm fereastra asociată cazului de utilizare Creare Cont.

În continuare prezentăm codul clasei ControllerCreareCont.

public class ControllerCreareCont {

private final String d=MVC.getInstance().CtrlC().getDelimitator();

private static final ControllerCreareCont instance=new ControllerCreareCont();

private ControllerCreareCont(){};

public static ControllerCreareCont getInstance(){

return instance;

}

public void cereCreareCont(JFrame parinte){

FereastraCont fereastra=new FereastraCont();

fereastra.creaza(parinte);

fereastra.afiseaza();

}

public boolean introduceDate(String nume, String prenume, String email, String parola){

if((boolean)MVC.getInstance().CtrlC().trimite("MngrC"+d+"verificaUnicitate"+d+email)){

Utilizator u=new Utilizator(nume,prenume,email,parola);

return (boolean)MVC.getInstance().CtrlC().trimite("MngrC"+d+"memoreazaCont", u);

} else{

return false;

}

}

}

În continuare prezentăm fereastra asociată cazului de utilizare Autentificare în sistem.

În continuare prezentăm codul clasei ControllerAutentificare.

public class ControllerAutentificare {

private Utilizator user=null;

private JFrame parinte;

private final String d=MVC.getInstance().CtrlC().getDelimitator();

private static final ControllerAutentificare instance=new ControllerAutentificare();

private ControllerAutentificare(){};

public static ControllerAutentificare getInstance(){

return instance;

}

public Utilizator getUser(){

return user;

}

public void resetUser(){

user=null;

}

public void cereAutentificare(JFrame parinte){

this.parinte=parinte;

FereastraAutentificare fereastra=new FereastraAutentificare();

fereastra.creaza(parinte);

fereastra.afiseaza();

}

public boolean introduceDate(String email, String parola){

Utilizator u=(Utilizator)MVC.getInstance().CtrlC().trimite("MngrC"+d+"verificaCont"+d+email+d+parola);

if(u!=null){

this.user=u;

FereastraOperatii fereastra=new FereastraOperatii();

fereastra.creaza(parinte);

fereastra.afiseaza();

return true;

} else {

return false;

}

}

}

În continuare prezentăm codul clasei ManagerConturi.

public class ManagerConturi {

private final Conexiune BD=Conexiune.getInstanta();

private static final ManagerConturi instance=new ManagerConturi();

private ManagerConturi(){};

public static ManagerConturi getInstance(){

return instance;

}

public boolean verificaUnicitate(String email){

if(email.contains("'")){

return false;

}

String interogare="SELECT * FROM Conturi WHERE Email='"+email+"' AND Admin=false;";

ResultSet rs=BD.interogheaza(interogare);

try {

if(rs.next()){

return false;

}

} catch(Exception e){

System.out.println(e.getMessage());

}

return true;

}

public boolean memoreazaCont(Utilizator u){

String nume=u.getNume();

String prenume=u.getPrenume();

String email=u.getEmail();

String parola=u.getParola();

if(nume.contains("'")||prenume.contains("'")||email.contains("'")||parola.contains("'")){

return false;

}

String actualizare="INSERT INTO Conturi (Nume, Prenume, Email, Parola) VALUES ('"+nume+"', '"+prenume+"', '"+email+"', '"+parola+"');";

return BD.actualizeaza(actualizare);

}

public Utilizator verificaCont(String email, String parola){

if(email.contains("'")||parola.contains("'")){

return null;

}

String interogare="SELECT * FROM Conturi WHERE Admin=false AND Email='"+email+"' AND Parola='"+parola+"';";

try {

ResultSet rs=BD.interogheaza(interogare);

if(rs.next()){

return new Utilizator(rs.getString("Nume"),rs.getString("Prenume"),rs.getString("Email"),rs.getString("Parola"));

}

} catch(Exception e){

System.out.println(e.getMessage());

}

return null;

}

}

Adăugare eveniment și Notificare utilizatori

Pentru a adăuga un eveniment un organizator trebuie să se autentifice din interfața grafică a Serverului. Apoi îi sunt prezentate o serie de ferestre în care poate introduce evenimente aparținând unei categorii existente sau poate introduce o categorie nouă. După ce introduce toate informațiile, inclusiv categoriile de locuri aferente noului eveniment, organizatorului i se cere o confirmare ulterior căreia evenimentul este salvat în baza de date, iar Serverul verifică preferințele aflate pe fiecare dintre conturile clienților, notificându-i pe cei interesați prin intermediul unui email.

Fereastra de autentificare este identică cu cea pentru clienți; în schimb funcționalitatea diferă, doar organizatorii având posibilitatea de a trece de acest pas.

În continuare prezentăm fereastra de introducere a datelor pentru un eveniment.

În continuare prezentăm fereastra de introducere a datelor pentru o categorie de locuri.

În continuare prezentăm codul clasei ControllerAdaugare.

public class ControllerAdaugare {

private Utilizator admin=null;

private final Conexiune BD=Conexiune.getInstanta();

private static ControllerAdaugare instance=new ControllerAdaugare();

private ControllerAdaugare(){};

public static ControllerAdaugare getInstance(){

return instance;

}

public Utilizator getAdmin(){

return admin;

}

public void resetAdmin(){

admin=null;

}

public boolean cereAdaugareEveniment(String email, String parola, JFrame parinte){

String interogare="SELECT * FROM Conturi WHERE Admin=true AND Email='"+email+"' AND Parola='"+parola+"';";

try {

ResultSet rs=BD.interogheaza(interogare);

if(rs.next()){

admin=new Utilizator(rs.getString("Nume"),rs.getString("Prenume"),rs.getString("Email"),rs.getString("Parola"));

FereastraOrganizator fereastra=new FereastraOrganizator();

fereastra.creaza(parinte);

fereastra.afiseaza();

return true;

}

} catch(Exception e){

System.out.println(e.getMessage());

}

return false;

}

public void introduceDate(String denumire, int categorie, String descriere, String data, int localitate, ArrayList<Eveniment.CategorieLocuri> locuri){

Eveniment e=new Eveniment(denumire,categorie,descriere,data,localitate);

for(int i=0;i<locuri.size();i++){

e.addCategorieLocuri(locuri.get(i));

}

e.setId(MVC.getInstance().MngrE().memoreaza(e));

MVC.getInstance().Email().notifica(e);

}

}

În continuare prezentăm codul clasei GestiuneEmail.

public class GestiuneEmail {

private final String username = "[anonimizat]",password = "administrator2015";

private final Conexiune BD=Conexiune.getInstanta();

private String d=MVC.getInstance().CtrlS().getDelimitator();

private static GestiuneEmail instance=new GestiuneEmail();

private GestiuneEmail(){};

public static GestiuneEmail getInstance(){

return instance;

}

private String formatareData(String data){

String luna,mesajf=new String();

String[] text1=data.split(" ");

String[] text2=text1[0].split("-");

mesajf+=Integer.parseInt(text2[2]);

switch (Integer.parseInt(text2[1])) {

case 1: luna = "Ianuarie";

break;

case 2: luna = "Februarie";

break;

case 3: luna = "Martie";

break;

case 4: luna = "Aprilie";

break;

case 5: luna = "Mai";

break;

case 6: luna = "Iunie";

break;

case 7: luna = "Iulie";

break;

case 8: luna = "August";

break;

case 9: luna = "Septembrie";

break;

case 10: luna = "Octombrie";

break;

case 11: luna = "Noiembrie";

break;

case 12: luna = "Decembrie";

break;

default: luna = "Invalid month";

break;

}

mesajf+=luna;

mesajf+=text2[0];

mesajf+=" ";

text2=text1[1].split(":");

mesajf+=Integer.parseInt(text2[0])+":";

if(Integer.parseInt(text2[1])<10){

mesajf+="0";

}

mesajf+=Integer.parseInt(text2[1]);

return mesajf;

}

public void notifica(Eveniment e){

String email="Un nou eveniment a fost adaugat care se aplica preferintelor dumneavoastra!\n\n"+e.getDenumire()+"\n";

String interogare="SELECT * FROM CategoriiEvenimente WHERE IdCategorie="+e.getIdCategorie();

ResultSet rs=BD.interogheaza(interogare);

try {

rs.next();

email+=rs.getString("Categorie");

} catch(Exception ex){

System.out.println(ex.getMessage());

}

String[] textData=formatareData(e.getData()).split(" ");

email+=" pe data de "+textData[0]+", la ora "+ textData[0]+", in localitatea ";

interogare="SELECT * FROM Localitati WHERE IdLocalitate="+e.getIdLocalitate();

rs=BD.interogheaza(interogare);

try {

rs.next();

email+=rs.getString("Localitate");

} catch(Exception ex){

System.out.println(ex.getMessage());

}

email+="\n\n"+e.getDescriere()+"\n\nAcest eveniment are "+e.getLocuri().size()+" categorii de bilete!\nPuteti intra in aplicatie pentru mai multe detalii!";

interogare="SELECT Conturi.Email, Preferinte.IdCategorie, Preferinte.IdLocalitate, Preferinte.Continut, Preferinte.DataInceput, Preferinte.DataSfarsit, Preferinte.OriceData FROM Conturi JOIN Preferinte ON Conturi.IdCont=Preferinte.IdCont;";

rs=BD.interogheaza(interogare);

String adrese="";

try{

while(rs.next()){

String oriceData="false";

if(rs.getString("OriceData").equals("1")){

oriceData="true";

}

ArrayList<String> filtrare=MVC.getInstance().MngrE().filtrare(rs.getString("Continut"), Integer.parseInt(rs.getString("IdCategorie")), rs.getString("DataInceput"), rs.getString("DataSfarsit"), oriceData, Integer.parseInt(rs.getString("IdLocalitate")));

for(int i=0;i<filtrare.size();i++){

String[] eveniment=filtrare.get(i).split(d);

if(e.getId()==Integer.parseInt(eveniment[0])){

if(!adrese.isEmpty()){

adrese+=",";

}

adrese+=rs.getString("Email");

System.out.println(rs.getString("Email"));

}

}

}

} catch(Exception ex){

System.out.println(ex.getMessage());

}

Properties props = new Properties();

props.put("mail.smtp.auth", "true");

props.put("mail.smtp.starttls.enable", "true");

props.put("mail.smtp.host", "smtp.gmail.com");

props.put("mail.smtp.port", "587");

Session session = Session.getInstance(props,

new Authenticator() {

protected PasswordAuthentication getPasswordAuthentication() {

return new PasswordAuthentication(username, password);

}

});

try {

Message message=new MimeMessage(session);

message.setFrom(new InternetAddress("[anonimizat]"));

message.setRecipients(Message.RecipientType.TO,InternetAddress.parse(adrese));

message.setSubject("Event-Hub -> Eveniment nou: "+e.getDenumire());

message.setText(email);

Transport.send(message);

} catch(Exception ex){

System.out.println(ex.getMessage());

}

}

}

Vizualizare eveniment și Rezervare bilet

Un client poate vizualiza evenimente, poate realiza o căutare filtrată după anumite criterii și poate rezerva un bilet care ulterior este trimis spre imprimare. Tot acest proces se realizează prin intermediul mai multor obiecte după cum urmează.

În continuare prezentăm fereastra de operații a sistemului Event-Hub.

În continuare prezentăm fereastra dedicată vizualizării evenimentelor.

În continuare prezentăm fereastra de selectare a criteriilor.

În continuare prezentăm fereastra de prezentare a unui eveniment.

În continuare prezentăm fereastra dedicată rezervării de bilete.

În continuare prezentăm fereastra dedicată selectării locurilor pe scaune.

În continuare prezentăm codul clasei ControllerEvenimente.

public class ControllerEvenimente {

private final String d=MVC.getInstance().CtrlC().getDelimitator();

private static final ControllerEvenimente instance=new ControllerEvenimente();

private ControllerEvenimente(){};

public static ControllerEvenimente getInstance(){

return instance;

}

public void cereListaEvenimente(JFrame parinte){

FereastraEvenimente fereastra=new FereastraEvenimente();

fereastra.creaza(parinte);

fereastra.afiseaza((ArrayList)MVC.getInstance().CtrlC().trimite("MngrE"+d+"lista"));

}

public void cereFiltrare(JFrame parinte){

MVC.getInstance().CtrlP().actualizeazaOptiuni();

FereastraCriterii fereastra=new FereastraCriterii();

fereastra.creaza(parinte);

fereastra.afiseaza();

}

public void seleceteazaCriterii(String continut, int categorie, String dataI, String dataS, boolean oriceData, int localitate, JFrame parinte){

((FereastraEvenimente)parinte).afiseaza((ArrayList)MVC.getInstance().CtrlC().trimite("MngrE"+d+"filtrare"+d+continut+d+categorie+d+dataI+d+dataS+d+oriceData+d+localitate));

}

public void selecteazaEveniment(String id, JFrame parinte){

FereastraEveniment fereastra=new FereastraEveniment();

Eveniment e=(Eveniment)MVC.getInstance().CtrlC().trimite("MngrE"+d+"eveniment"+d+id);

fereastra.creaza(parinte,e);

fereastra.afiseaza();

}

}

În continuare prezentăm codul clasei ManagerEvenimente.

public class ManagerEvenimente {

private final Conexiune BD=Conexiune.getInstanta();

private final String d=MVC.getInstance().CtrlS().getDelimitator();

private static final ManagerEvenimente instance=new ManagerEvenimente();

private ManagerEvenimente(){};

public static ManagerEvenimente getInstance(){

return instance;

}

private String formatareData(String data){

String luna,mesajf=new String();

String[] text1=data.split(" ");

String[] text2=text1[0].split("-");

mesajf+=Integer.parseInt(text2[2]);

switch (Integer.parseInt(text2[1])) {

case 1: luna = "Ianuarie";

break;

case 2: luna = "Februarie";

break;

case 3: luna = "Martie";

break;

case 4: luna = "Aprilie";

break;

case 5: luna = "Mai";

break;

case 6: luna = "Iunie";

break;

case 7: luna = "Iulie";

break;

case 8: luna = "August";

break;

case 9: luna = "Septembrie";

break;

case 10: luna = "Octombrie";

break;

case 11: luna = "Noiembrie";

break;

case 12: luna = "Decembrie";

break;

default: luna = "Invalid month";

break;

}

mesajf+=luna;

mesajf+=text2[0];

mesajf+=" ";

text2=text1[1].split(":");

mesajf+=Integer.parseInt(text2[0])+":";

if(Integer.parseInt(text2[1])<10){

mesajf+="0";

}

mesajf+=Integer.parseInt(text2[1]);

return mesajf;

}

private String dataText(Date data){

Date moment=data;

String text=(1900+moment.getYear())+"-"+(moment.getMonth()+1)+"-"+moment.getDate()+" "+moment.getHours()+":"+moment.getMinutes()+":"+moment.getSeconds();

return text;

}

public ArrayList lista(){

ArrayList<String> evenimente=new ArrayList<>();

String interogare="SELECT Evenimente.IdEveniment, Evenimente.Denumire, CategoriiEvenimente.Categorie, Localitati.Localitate, Evenimente.DataEveniment FROM Evenimente JOIN CategoriiEvenimente ON Evenimente.IdCategorie=CategoriiEvenimente.IdCategorie JOIN Localitati ON Evenimente.IdLocalitate=Localitati.IdLocalitate WHERE Evenimente.DataEveniment>='"+dataText(new Date())+"' ORDER BY Evenimente.DataEveniment DESC;";

String eveniment;

try{

ResultSet rs=BD.interogheaza(interogare);

while(rs.next()){

eveniment=rs.getString(1)+d+rs.getString(2)+d+rs.getString(3)+d+rs.getString(4)+d+formatareData(rs.getString(5));

evenimente.add(eveniment);

}

} catch(Exception e){

System.out.println(e.getMessage());

}

return evenimente;

}

public ArrayList filtrare(String continut, int categorie, String dataI, String dataS, String oriceData, int localitate){

ArrayList<String> evenimente=new ArrayList<>();

String interogare="SELECT Evenimente.IdEveniment, Evenimente.Denumire, CategoriiEvenimente.Categorie, Localitati.Localitate, Evenimente.DataEveniment FROM Evenimente JOIN CategoriiEvenimente ON Evenimente.IdCategorie=CategoriiEvenimente.IdCategorie JOIN Localitati ON Evenimente.IdLocalitate=Localitati.IdLocalitate WHERE Evenimente.DataEveniment>='"+dataText(new Date())+"'";

String verificare=interogare;

if(oriceData.equals("false")){

interogare+=" AND Evenimente.DataEveniment BETWEEN '"+dataI+"' AND '"+dataS+"'";

}

if(!continut.isEmpty()){

interogare+=" AND (Evenimente.Denumire LIKE '%"+continut+"%' OR Evenimente.Descriere LIKE '%"+continut+"%')";

}

if(categorie!=1){

interogare+=" AND Evenimente.IdCategorie="+categorie;

}

if(localitate!=1){

String interogare_localitati="SELECT * FROM Localitati WHERE Localitate='Toate Localitatile';";

int judet=0;

try {

ResultSet rs=BD.interogheaza(interogare_localitati);

while(rs.next()){

if(judet==-1){

judet+=Integer.parseInt(rs.getString("IdLocalitate"));

}

if(Integer.parseInt(rs.getString("IdLocalitate"))==localitate){

judet=-1;

}

}

} catch(Exception e){

System.out.println(e.getMessage());

}

if(judet==-1){

interogare_localitati="SELECT COUNT(`IdLocalitate`) AS 'numar' FROM `Localitati`;";

try {

judet=0;

ResultSet rs=BD.interogheaza(interogare_localitati);

rs.next();

judet=Integer.parseInt(rs.getString("numar"));

} catch(Exception e){

System.out.println(e.getMessage());

}

}

if(judet==0){

interogare+=" AND Evenimente.IdLocalitate="+localitate;

} else {

interogare+=" AND Evenimente.IdLocalitate BETWEEN "+localitate+" AND "+judet;

}

}

interogare+=" ORDER BY Evenimente.DataEveniment DESC;";

System.out.println(interogare);

String eveniment;

try {

ResultSet rs=BD.interogheaza(interogare);

while(rs.next()){

eveniment=rs.getString(1)+d+rs.getString(2)+d+rs.getString(3)+d+rs.getString(4)+d+formatareData(rs.getString(5));

evenimente.add(eveniment);

}

} catch(Exception e){

System.out.println(e.getMessage());

}

return evenimente;

}

public Eveniment eveniment(int id){

Eveniment e=null;

String interogare="SELECT Evenimente.Denumire, CategoriiEvenimente.Categorie, Evenimente. Descriere, Evenimente.DataEveniment, Localitati.Localitate FROM Evenimente JOIN CategoriiEvenimente ON Evenimente.IdCategorie=CategoriiEvenimente.IdCategorie JOIN Localitati ON Evenimente.IdLocalitate=Localitati.IdLocalitate WHERE Evenimente.IdEveniment="+id+";";

try {

ResultSet rs=BD.interogheaza(interogare);

if(rs.next()){

e=new Eveniment(rs.getString("Denumire"),rs.getString("Categorie"),rs.getString("Descriere"),formatareData(rs.getString("DataEveniment")),rs.getString("Localitate"));

}

} catch(Exception ex){

System.out.println(ex.getMessage());

}

e.setId(id);

interogare="SELECT * FROM CategoriiLocuri WHERE IdEveniment="+id+";";

try {

ResultSet rs=BD.interogheaza(interogare);

while(rs.next()){

boolean scaune=false;

if(rs.getString("LocuriPeScaune").equals("1")){

scaune=true;

}

Eveniment.CategorieLocuri cl=new Eveniment.CategorieLocuri(rs.getString("Denumire"),Float.parseFloat(rs.getString("Pret")),Integer.parseInt(rs.getString("NrLocuriDisponibile")),scaune,Integer.parseInt(rs.getString("PrimulRand")),Integer.parseInt(rs.getString("UltimulRand")),Integer.parseInt(rs.getString("PrimulScaun")),Integer.parseInt(rs.getString("UltimulScaun")));

cl.setId(Integer.parseInt(rs.getString("IdCategorieLocuri")));

e.addCategorieLocuri(cl);

}

} catch(Exception ex){

System.out.println(ex.getMessage());

}

return e;

}

public int memoreaza(Eveniment e){

String actualizare="INSERT INTO Evenimente(IdCategorie,Denumire,Descriere,DataEveniment,IdLocalitate) "

+ "VALUES ("+e.getIdCategorie()+",'"+e.getDenumire()+"','"+e.getDescriere()+"','"+e.getData()+"',"+e.getIdLocalitate()+");";

BD.actualizeaza(actualizare);

String interogare="SELECT * FROM Evenimente WHERE IdCategorie="+e.getIdCategorie()+" AND Denumire='"+e.getDenumire()+"' AND Descriere='"+e.getDescriere()+"' AND IdLocalitate="+e.getIdLocalitate()+" ORDER BY IdEveniment DESC;";

ResultSet rs=BD.interogheaza(interogare);

int IdEveniment=0;

try {

rs.next();

IdEveniment=Integer.parseInt(rs.getString("IdEveniment"));

} catch(Exception ex){

System.out.println(ex.getMessage());

}

ArrayList<Eveniment.CategorieLocuri> locuri=e.getLocuri();

for(int i=0;i<locuri.size();i++){

locuri.get(i).setId(IdEveniment);

Eveniment.CategorieLocuri cl=locuri.get(i);

actualizare="INSERT INTO CategoriiLocuri (IdEveniment, Denumire, Pret, NrLocuriDisponibile, LocuriPeScaune, PrimulRand, UltimulRand, PrimulScaun, UltimulScaun) "

+ "VALUES ("+IdEveniment+", '"+cl.denumire+"', "+cl.pret+", "+cl.nr+", "+cl.scaune+", "+cl.pr+", "+cl.ur+", "+cl.ps+", "+cl.us+");";

BD.actualizeaza(actualizare);

}

return IdEveniment;

}

}

În continuare prezentăm codul clasei ControllerRezervari.

public class ControllerRezervari {

private Eveniment ev;

private Bilet b;

private final String d=MVC.getInstance().CtrlC().getDelimitator();

private static final ControllerRezervari instance=new ControllerRezervari();

private ControllerRezervari(){};

public static ControllerRezervari getInstance(){

return instance;

}

public void cereRezervare(Eveniment ev, JFrame parinte){

this.ev=ev;

if(ev.getLocuri().isEmpty()){

JOptionPane.showMessageDialog(parinte,"Acest eveniment nu are categorii de bilete!","Atentionare",JOptionPane.WARNING_MESSAGE);

return;

}

ArrayList<String> locuriOcupate=(ArrayList)MVC.getInstance().CtrlC().trimite("MngrR"+d+"rezervari"+d+ev.getId());

FereastraRezervare fereastra=new FereastraRezervare();

fereastra.creaza(ev,parinte);

fereastra.afiseaza(locuriOcupate);

}

public void selecteazaLocuri(JFrame parinte, ArrayList<String> locuri){

Rezervare r=new Rezervare(MVC.getInstance().CtrlA().getUser());

ArrayList<Rezervare.Loc> lista=new ArrayList<>();

for(int i=0;i<locuri.size();i++){

String[] loc=locuri.get(i).split(d);

lista.add(new Rezervare.Loc(loc[0],Integer.parseInt(loc[1]),Float.parseFloat(loc[2]),Integer.parseInt(loc[3]),Integer.parseInt(loc[4])));

}

r.setList(lista);

boolean confirmat=cereConfirmare(parinte,r);

if(confirmat){

confirmaRezervare(r);

}

}

public boolean cereConfirmare(JFrame p, Rezervare r){

int raspuns=JOptionPane.showConfirmDialog(p,"Ati selectat in total "+r.getNrLocuri()+" locuri!\nPretul total al acestei rezervari va fi "+r.calculeazaCost()+"!\n\nConfirmati rezervarea?","Confirmare",JOptionPane.YES_NO_OPTION);

return raspuns==JOptionPane.YES_OPTION;

}

public void confirmaRezervare(Rezervare r){

Bilet b=(Bilet)MVC.getInstance().CtrlC().trimite("MngrR"+d+"memoreaza",r);

System.out.println(b);

if(b!=null){

this.b=b;

MVC.getInstance().CtrlR().imprimaBilet();

} else {

JOptionPane.showMessageDialog(null,"Ne pare rau!\nO parte din locuri au fost deja rezervate intre timp!\n Nu va putem indeplini cererea!", "Eroare", JOptionPane.ERROR_MESSAGE);

}

}

public void imprimaBilet(){

PrinterJob job=PrinterJob.getPrinterJob();

PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();

job.setPrintable(b);

boolean imprimat=false;

while(!imprimat){

if(job.printDialog()){

try {

job.print(aset);

imprimat=true;

} catch(PrinterException | HeadlessException ex){

System.out.println(ex.getMessage());

imprimat=false;

JOptionPane.showMessageDialog(null, "A aparut o eroare la imprimare!\nIncercati sa folositi setari diferite!", "Eroare", JOptionPane.ERROR_MESSAGE);

}

} else {

JOptionPane.showMessageDialog(null, "Rezervarea a fost efectuata!\nTrebuie sa imprimati biletul!", "Avertizare", JOptionPane.WARNING_MESSAGE);

}

}

JOptionPane.showMessageDialog(null,"Rezervarea dumneavoastra a fost realizata cu succes!");

}

}

În continuare prezentăm codul clasei ManagerRezervari.

public class ManagerRezervari {

private final Conexiune BD=Conexiune.getInstanta();

private final String d=MVC.getInstance().CtrlS().getDelimitator();

private static final ManagerRezervari instance=new ManagerRezervari();

private ManagerRezervari(){};

public static ManagerRezervari getInstance(){

return instance;

}

public ArrayList rezervari(int id){

ArrayList<String> locuri=new ArrayList<>();

String interogare="SELECT LocuriRezervate.IdCategorieLocuri, LocuriRezervate.Rand, LocuriRezervate.Scaun FROM CategoriiLocuri JOIN LocuriRezervate ON CategoriiLocuri.IdCategorieLocuri=LocuriRezervate.IdCategorieLocuri WHERE CategoriiLocuri.IdEveniment="+id+";";

try {

ResultSet rs=BD.interogheaza(interogare);

while(rs.next()){

locuri.add(rs.getString("IdCategorieLocuri")+d+rs.getString("Rand")+d+rs.getString("Scaun"));

}

} catch(Exception e){

System.out.println(e.getMessage());

}

return locuri;

}

public Bilet memoreaza(Rezervare r){

String interogare="SELECT * FROM Conturi WHERE Email='"+r.getCont().getEmail()+"' AND Parola='"+r.getCont().getParola()+"';";

String actualizare="INSERT INTO Rezervari (IdCont) VALUES (";

ResultSet rs=BD.interogheaza(interogare);

try {

rs.next();

actualizare+=rs.getString("IdCont")+");";

} catch(Exception e){

System.out.println(e.getMessage());

}

BD.actualizeaza(actualizare);

interogare="SELECT * FROM Rezervari ORDER BY IdRezervare DESC;";

rs=BD.interogheaza(interogare);

try {

rs.next();

actualizare="INSERT INTO LocuriRezervate (IdRezervare, IdCategorieLocuri, Rand, Scaun) VALUES ("+rs.getString("IdRezervare")+", ";

} catch(Exception e){

System.out.println(e.getMessage());

}

for(int i=0;i<r.getList().size();i++){

String text=((Rezervare.Loc)r.getList().get(i)).IdCategorie+", ";

text+=((Rezervare.Loc)r.getList().get(i)).rand+", ";

text+=((Rezervare.Loc)r.getList().get(i)).scaun+");";

BD.actualizeaza(actualizare+text);

}

int IdEveniment=0;

interogare="SELECT Evenimente.IdEveniment, CategoriiLocuri.Denumire FROM Evenimente JOIN CategoriiLocuri ON Evenimente.IdEveniment=CategoriiLocuri.IdEveniment "

+ "WHERE CategoriiLocuri.IdCategorieLocuri="+((Rezervare.Loc)r.getList().get(0)).IdCategorie;

rs=BD.interogheaza(interogare);

try {

rs.next();

IdEveniment=Integer.parseInt(rs.getString(1));

} catch(Exception e){

System.out.println(e.getMessage());

}

String denumire=null, categorie=null, descriere=null, data=null, oras=null;

interogare="SELECT Evenimente.Denumire, CategoriiEvenimente.Categorie, Evenimente.Descriere, Evenimente.DataEveniment, Localitati.Localitate FROM "

+ "Evenimente JOIN CategoriiEvenimente ON Evenimente.IdCategorie=CategoriiEvenimente.IdCategorie JOIN Localitati ON Evenimente.IdLocalitate=Localitati.IdLocalitate "

+ "WHERE IdEveniment="+IdEveniment+";";

rs=BD.interogheaza(interogare);

try {

rs.next();

denumire=rs.getString("Denumire");

categorie=rs.getString("Categorie");

descriere=rs.getString("Descriere");

data=rs.getString("DataEveniment");

oras=rs.getString("Localitate");

} catch(Exception e){

System.out.println(e.getMessage());

}

Bilet b=new Bilet(r,denumire,categorie,descriere,data,oras);

return b;

}

}

Concluzii

Lucrarea de față prezintă procesul de dezvoltare al unui sistem software având ca și caz particular sistemul Event-Hub. Contribuțiile personale aduse lucrării de față au constat în definirea problemei, analiza sistemului software, proiectarea aplicației și a bazei de date și implementarea aplicației.

În etapa de definire a problemei am realizat o descriere a problemei abordate. Ulterior am identificat și stabilit care sunt participanții în procesul de dezvoltare, obiectivele pe care sistemul trebuie să le îndeplinească precum și câteva scenarii potențiale.

Pe baza acestora, am trecut la etapa de analiză a sistemului în care am transpus obiectivele în cerințe și cazuri de utilizare pentru care am scris fluxul principal și am creat diagrame de secvențe de sistem iar la sfârșitul acestei etapei am creat o diagramă de clase a modelului domeniului.

Având cerințele sistemului, am proiectat baza de date și aplicația folosind diverse modele de proiectare și stiluri arhitecturale prezentate în capitolul aferent. Astfel am realizat pentru fiecare caz de utilizare câte o diagramă de secvențe și una de clase de proiectare pe baza cărora am realizat ulterior implementarea.

Astfel am ajuns de la tema aleasă la produsul final reprezentând lucrarea de față, sistemul software propriu-zis și elementele constituiente ale acestuia. Aplicația realizată poate fi utilizată cu succes în a opta pentru notificări prin intermediul emailului, a vizualiza evenimentele disponibile la momentul curent și a rezerva și imprima bilete la acestea.

Anexe

Trigger SQL

Vă prezint triggerul creat pentru a adăuga opțiunea „Toate Localitatile” dintr-un nou județ adăugat pentru a folosi la criteriile dedicate căutării și preferințelor.

CREATE TRIGGER `intreg_judetul` AFTER INSERT ON `Judete` FOR EACH ROW

BEGIN

INSERT INTO `Localitati` (IdJudet,Localitate) values (NEW.`IDJudet`,'Toate Localitatile');

END

Procedură SQL

Vă prezint în cele ce urmează procedura creată în cadrul acestei lucrări pentru a popula tabelele Judete și Localitati din cadrul bazei de date. Localitățile introduse reprezintă cele 103 municipii ale României.

CREATE PROCEDURE judete_localitati()

BEGIN

insert into `judete` (Judet) values ("Toate Judetele"); #1 pentru preferinte/criterii de cautare

insert into `judete` (Judet) values ("Alba"); #2

insert into `localitati` (IdJudet,Localitate) values (2,"Aiud");

insert into `localitati` (IdJudet,Localitate) values (2,"Alba Iulia");

insert into `localitati` (IdJudet,Localitate) values (2,"Blaj");

insert into `localitati` (IdJudet,Localitate) values (2,"Sebes");

insert into `judete` (Judet) values ("Arad"); #3

insert into `localitati` (IdJudet,Localitate) values (3,"Arad");

insert into `judete` (Judet) values ("Arges"); #4

insert into `localitati` (IdJudet,Localitate) values (4,"Campulung");

insert into `localitati` (IdJudet,Localitate) values (4,"Curtea de Arges");

insert into `localitati` (IdJudet,Localitate) values (4,"Pitesti");

insert into `judete` (Judet) values ("Bacau"); #5

insert into `localitati` (IdJudet,Localitate) values (5,"Bacau");

insert into `localitati` (IdJudet,Localitate) values (5,"Moinesti");

insert into `localitati` (IdJudet,Localitate) values (5,"Onesti");

insert into `judete` (Judet) values ("Bihor"); #6

insert into `localitati` (IdJudet,Localitate) values (6,"Beius");

insert into `localitati` (IdJudet,Localitate) values (6,"Marghita");

insert into `localitati` (IdJudet,Localitate) values (6,"Oradea");

insert into `localitati` (IdJudet,Localitate) values (6,"Salonta");

insert into `judete` (Judet) values ("Bistrita-Nasaud"); #7

insert into `localitati` (IdJudet,Localitate) values (7,"Bistrita");

insert into `judete` (Judet) values ("Botosani"); #8

insert into `localitati` (IdJudet,Localitate) values (8,"Botosani");

insert into `localitati` (IdJudet,Localitate) values (8,"Dorohoi");

insert into `judete` (Judet) values ("Braila"); #9

insert into `localitati` (IdJudet,Localitate) values (9,"Braila");

insert into `judete` (Judet) values ("Brasov"); #10

insert into `localitati` (IdJudet,Localitate) values (10,"Brasov");

insert into `localitati` (IdJudet,Localitate) values (10,"Codlea");

insert into `localitati` (IdJudet,Localitate) values (10,"Fagaras");

insert into `localitati` (IdJudet,Localitate) values (10,"Sacele");

insert into `judete` (Judet) values ("Bucuresti"); #11

insert into `localitati` (IdJudet,Localitate) values (11,"Bucuresti");

insert into `judete` (Judet) values ("Buzau"); #12

insert into `localitati` (IdJudet,Localitate) values (12,"Buzau");

insert into `localitati` (IdJudet,Localitate) values (12,"Ramnicu Sarat");

insert into `judete` (Judet) values ("Calarasi"); #13

insert into `localitati` (IdJudet,Localitate) values (13,"Calarasi");

insert into `localitati` (IdJudet,Localitate) values (13,"Oltenita");

insert into `judete` (Judet) values ("Caras-Severin"); #14

insert into `localitati` (IdJudet,Localitate) values (14,"Caransebes");

insert into `localitati` (IdJudet,Localitate) values (14,"Resita");

insert into `judete` (Judet) values ("Cluj"); #15

insert into `localitati` (IdJudet,Localitate) values (15,"Campia Turzii");

insert into `localitati` (IdJudet,Localitate) values (15,"Cluj-Napoca");

insert into `localitati` (IdJudet,Localitate) values (15,"Dej");

insert into `localitati` (IdJudet,Localitate) values (15,"Gherla");

insert into `localitati` (IdJudet,Localitate) values (15,"Turda");

insert into `judete` (Judet) values ("Constanta"); #16

insert into `localitati` (IdJudet,Localitate) values (16,"Constanta");

insert into `localitati` (IdJudet,Localitate) values (16,"Mangalia");

insert into `localitati` (IdJudet,Localitate) values (16,"Medgidia");

insert into `judete` (Judet) values ("Covasna"); #17

insert into `localitati` (IdJudet,Localitate) values (17,"Sfantu Gheorghe");

insert into `localitati` (IdJudet,Localitate) values (17,"Targu Secuiesc");

insert into `judete` (Judet) values ("Dambovita"); #18

insert into `localitati` (IdJudet,Localitate) values (18,"Moreni");

insert into `localitati` (IdJudet,Localitate) values (18,"Targoviste");

insert into `judete` (Judet) values ("Dolj"); #19

insert into `localitati` (IdJudet,Localitate) values (19,"Bailesti");

insert into `localitati` (IdJudet,Localitate) values (19,"Calafat");

insert into `localitati` (IdJudet,Localitate) values (19,"Craiova");

insert into `judete` (Judet) values ("Galati"); #20

insert into `localitati` (IdJudet,Localitate) values (20,"Galati");

insert into `judete` (Judet) values ("Giurgiu"); #21

insert into `localitati` (IdJudet,Localitate) values (21,"Giurgiu");

insert into `judete` (Judet) values ("Gorj"); #22

insert into `localitati` (IdJudet,Localitate) values (22,"Motru");

insert into `localitati` (IdJudet,Localitate) values (22,"Targu Jiu");

insert into `judete` (Judet) values ("Harghita"); #23

insert into `localitati` (IdJudet,Localitate) values (23,"Gheorgheni");

insert into `localitati` (IdJudet,Localitate) values (23,"Miercurea Ciuc");

insert into `localitati` (IdJudet,Localitate) values (23,"Odorheiu Secuiesc");

insert into `localitati` (IdJudet,Localitate) values (23,"Toplita");

insert into `judete` (Judet) values ("Hunedoara"); #24

insert into `localitati` (IdJudet,Localitate) values (24,"Brad");

insert into `localitati` (IdJudet,Localitate) values (24,"Deva");

insert into `localitati` (IdJudet,Localitate) values (24,"Hunedoara");

insert into `localitati` (IdJudet,Localitate) values (24,"Lupeni");

insert into `localitati` (IdJudet,Localitate) values (24,"Orastie");

insert into `localitati` (IdJudet,Localitate) values (24,"Petrosani");

insert into `localitati` (IdJudet,Localitate) values (24,"Vulcan");

insert into `judete` (Judet) values ("Ialomita"); #25

insert into `localitati` (IdJudet,Localitate) values (25,"Fetesti");

insert into `localitati` (IdJudet,Localitate) values (25,"Slobozia");

insert into `localitati` (IdJudet,Localitate) values (25,"Urziceni");

insert into `judete` (Judet) values ("Iasi"); #26

insert into `localitati` (IdJudet,Localitate) values (26,"Iasi");

insert into `localitati` (IdJudet,Localitate) values (26,"Pascani");

insert into `judete` (Judet) values ("Ilfov"); #27

insert into `judete` (Judet) values ("Maramures"); #28

insert into `localitati` (IdJudet,Localitate) values (28,"Baia Mare");

insert into `localitati` (IdJudet,Localitate) values (28,"Sighetu Marmatiei");

insert into `judete` (Judet) values ("Mehedinti"); #29

insert into `localitati` (IdJudet,Localitate) values (29,"Drobeta-Turnu Severin");

insert into `localitati` (IdJudet,Localitate) values (29,"Orsova");

insert into `judete` (Judet) values ("Mures"); #30

insert into `localitati` (IdJudet,Localitate) values (30,"Reghin");

insert into `localitati` (IdJudet,Localitate) values (30,"Sighisoara");

insert into `localitati` (IdJudet,Localitate) values (30,"Targu Mures");

insert into `localitati` (IdJudet,Localitate) values (30,"Tarnaveni");

insert into `judete` (Judet) values ("Neamt"); #31

insert into `localitati` (IdJudet,Localitate) values (31,"Piatra Neamt");

insert into `localitati` (IdJudet,Localitate) values (31,"Roman");

insert into `judete` (Judet) values ("Olt"); #32

insert into `localitati` (IdJudet,Localitate) values (32,"Caracal");

insert into `localitati` (IdJudet,Localitate) values (32,"Slatina");

insert into `judete` (Judet) values ("Prahova"); #33

insert into `localitati` (IdJudet,Localitate) values (33,"Campina");

insert into `localitati` (IdJudet,Localitate) values (33,"Ploiesti");

insert into `judete` (Judet) values ("Salaj"); #34

insert into `localitati` (IdJudet,Localitate) values (34,"Zalau");

insert into `judete` (Judet) values ("Satu Mare"); #35

insert into `localitati` (IdJudet,Localitate) values (35,"Carei");

insert into `localitati` (IdJudet,Localitate) values (35,"Satu Mare");

insert into `judete` (Judet) values ("Sibiu"); #36

insert into `localitati` (IdJudet,Localitate) values (36,"Medias");

insert into `localitati` (IdJudet,Localitate) values (36,"Sibiu");

insert into `judete` (Judet) values ("Suceava"); #37

insert into `localitati` (IdJudet,Localitate) values (37,"Campulung Moldovenesc");

insert into `localitati` (IdJudet,Localitate) values (37,"Falticeni");

insert into `localitati` (IdJudet,Localitate) values (37,"Radauti");

insert into `localitati` (IdJudet,Localitate) values (37,"Suceava");

insert into `localitati` (IdJudet,Localitate) values (37,"Vatra Dornei");

insert into `judete` (Judet) values ("Teleorman"); #38

insert into `localitati` (IdJudet,Localitate) values (38,"Alexandria");

insert into `localitati` (IdJudet,Localitate) values (38,"Rosiorii de Vede");

insert into `localitati` (IdJudet,Localitate) values (38,"Turnu Magurele");

insert into `judete` (Judet) values ("Timis"); #39

insert into `localitati` (IdJudet,Localitate) values (39,"Lugoj");

insert into `localitati` (IdJudet,Localitate) values (39,"Timisoara");

insert into `judete` (Judet) values ("Tulcea"); #40

insert into `localitati` (IdJudet,Localitate) values (40,"Tulcea");

insert into `judete` (Judet) values ("Valcea"); #41

insert into `localitati` (IdJudet,Localitate) values (41,"Dragasani");

insert into `localitati` (IdJudet,Localitate) values (41,"Ramnicu Valcea");

insert into `judete` (Judet) values ("Vaslui"); #42

insert into `localitati` (IdJudet,Localitate) values (42,"Barlad");

insert into `localitati` (IdJudet,Localitate) values (42,"Husi");

insert into `localitati` (IdJudet,Localitate) values (42,"Vaslui");

insert into `judete` (Judet) values ("Vrancea"); #43

insert into `localitati` (IdJudet,Localitate) values (43,"Adjud");

insert into `localitati` (IdJudet,Localitate) values (43,"Focsani");

END

Bibliografie

Dorin-Mircea Popovici (coordonator), Crenguța-Mădălina Bogdan, Andrei Rusu, Ozten Chelai, Aurelian Nicola – “MEDII VIRTUALE multimodale distribuite”, volumul 1, Editura Universitaria Craiova, Editura PROUNIVERSITARIA București, 2014

Dorin-Mircea Popovici (coordonator), Christian Mancaș, Crenguța-Mădălina Bogdan, Eugen Zaharescu – “MEDII VIRTUALE multimodale distribuite”, volumul 2, Editura Universitaria Craiova, Editura PROUNIVERSITARIA București, 2014

Similar Posts

  • Clase de Functii Univalente

    Cap.1 Clase speciale de funcții univalente. În acest capitol voi prezenta studiul unor clase de funcții univalente caracterizate prin proprietăți geometrice remarcabile, proprietăți care se exprimă analitic prin anumite inegalități diferențiale. Aceste condiții analitice care caracterizează acste clase reprezintă condiții suficiente de univalență. 1.1 Funcții stelate Definiția1: Fie funcția cu f(0)=0. Spunem că funcția f…

  • Teoria Fotosferelor Stelare

    I. INTRODUCERE Astronomia este o ramură a științelor naturii, care se ocupă în mod special cu studiul obiectelor cerești și al întregului univers. Folosirea instrumentelor matematice precum și realizările științelor fizice și tehnice. Astronomia studiază universul care ne înconjoară, din care face parte și Pământul cât și o infinitate de alte obiecte cerești. Astrofizica este…

  • Arhitectura Soft Pentru Un Magazin Online Care Ofera Servicii de Gazduire Pagini Web

    LUCRARE DE ABSOLVIRE Arhitectura soft pentru un magazin online care ofera servicii de gazduire pagini web Cuprins CuprinsIntroducere Capitolul 1 – Structura generala 1.1 Servicii de gazduire 1.2 Domenii 1.3 E-mail 1.4 Coșul de cumparaturi 1.5 Casa 1.6 Structura site Capitolul 2 – MySQL 2.1 Colecții de date 2.2 Ce este MySQL 2.3 Ce înseamnă…

  • Aplicatii Inteligente In Administratia Publica

    Introducere Organizațiile din sectorul public sunt constrânse să-și modifice politica internă, să își automatizeze procesele, să devină mai transparente și mai deschise în relația cu publicul(Prutianu, Ș., Comunicare și negociere în afaceri, Ed. Polirom, Iași, 1998). Informatizarea administrației publice poate să pară un concept abstract, mult prea complex pentru a putea fi înțeles și mult…

  • Sistem Informatic Pentru Evidenta Statistica In Activitati Sportive

    Sisteme și Tehnologii Informatice Avansate Sistem informatic pentru evidența statistică în activități sportive Argument În prezentarea de față voi aborda principalele aspecte ale bazei de date folosită de o echipa de fotbal pentru gestionarea contractelor încheiate cu fotbalistii, din perspectiva proiectantului de aplicații, utilizând ȋn realizarea sa SGBD-ul SQL Server, server puternic orientat pe performanță…

  • Solutii de Securitate de Tip Firewall

    INTRODUCERE CAPITOLUL I – SOLUȚII DE SECURITATE……………………………………… CAPITOLUL II – FIREWALL……………………………………………………….. 2.1 Istoria Firewall-ului…………………………………………………………. 2.2 Generalitati………………………………………………………………….. 2.3 Componentele unui firewall………………………………………………… 2.4 Politica unui firewall………………………………………………………… 2.5 Functionare…………………………………………………………………. 2.6 Avantajele și dezavantajele folosirii unui firewall…………………………. 2.7 Ce poate și ce nu poate face un firewall……………………………………. CAPITOLUL III – CONFIGURAREA UNUI FIREWALL……………………….. Windows Firewall……………………………………………………………………….. Windows 7……………………………………………………………………………… Comodo………………………………………………………………………………… Zone…