Instrument de Evaluare al Referintelor

Capitolul 1. Introducere

1.1. Obiectivele lucrării de licență

1.2. Structura lucrării de licență

Capitolul 2. Design de elemente grafice

2.1. Introducere

2.2. Raport tehnic

2.2.1. Controale, proprietăți și evenimente în general

2.2.2. Spații de nume în XAML

2.2.3. Window

2.2.4. Menu

2.2.5. Grid

2.2.6. DataGrid

2.2.7. GridSplitter

2.2.8. XmlDataProvider

2.3. Interfața grafică a aplicației ”Instrument de evaluare al referințelor”

Capitolul 3. Logica de funcționalitate a aplicației ”Instrument de evaluare al referințelor”

3.1. Introducere

3.2. Suport tehnic

3.2.1. Punct de intrare

3.2.2. Suportul documentației Xml

3.2.3. Definiția unui obiect

3.2.4. Serviciile unui obiect

3.2.5. Proprietățile de incluziune ale C#

3.2.6. Spații de nume

3.2.7. Variabile în cadrul .NET

3.2.8. Principii generale ale moștenirii

3.2.9. Polimorfismul

3.2.10. Tratarea excepțiilor

3.2.11. Fire de execuție și procese

3.2.12. Xml

3.3. Logica operațională

3.3.1. Introducere

3.3.2. Raportul tehnic

3.4. Aplicabilitatea în proiect

Capitolul 4. Concluzia

4.1. Îmbunătățiri viitoare:

Capitolul 5. Bibliografie

Introducere

Grupul Schaeffler este cel mai mare producător de lagăre la nivel global,compania produce rulmenți și ghidaje liniare pentru un număr mare de aplicații cum ar fi sistemele de axe de transmisie automate și manuale, seturi de planetare pentru tren și turbine eoliene.

BearinX a fost creată pentru a estima durata de viață a componentelor fabricate in Schaeffler, fiind cea mai bună aplicație de simulare de calcule a acestei durate la nivel global.

Toate calculele sunt extrem de precise cum ar fi luarea în considerare presiunea de contact a fiecărui element într-un sistem complex de viteze. Poate fi folosit pentru a analiza pentru a analiza o gamă largă de rulmenți variind de la rulmenți singuri la sisteme complexe de ghidare liniară.

BearinX are aproximativ 2500 utilizatori interni și mii de utilizatori a unei versiuni limitate ca și clienți, există o versiune specială pentru clienții fideli cu mai multe opțiuni și o versiune online folosită de aproximativ 400 companii și universități. Conține aproximativ 1.4 milioane de linii de cod și aproximativ 5000 de fișiere în suita de teste de regresie. Din cauza complexității sale, cantitatea vastă de clienții, corectitudinea calculelor este foarte importantă, aceste lucruri ar trebui sa indice cât de dificilă este sarcina de a le ține corecte.

Cum arată imaginea modulului de calcul?

Fig. 1.1. Fereastră de lucru în BearinX

În partea stangă a ferestrei este un toolbar care conține butoane pentru diferite acțiuni care pot fi efectuate pe obiecte 3d și în partea dreaptă este o arborescență cu toate subcomponentele și subansamblele obiectului. În vederea arborescentă când apăsăm click dreapta, o nouă fereastră este deschisă cu toate denumirile proprietăților și valorile proprietăților pe care le are obiectul.

Rezultatul din BearinX poate fi stocat local într-un folmular ca acesta:

Fig. 1.2. Raport rezultat din aplicația BearinX

Principalul motiv pentru care ”Instrumentul de evaluare al referințelor” este solicitat, este găsirea schimbărilor neașteptate la rezultatele aplicației BearinX, actualul mod de a descoperi aceste diferente și anume deschiderea rezultatelor într-o pagină Web nu oferă user–ului toate detalile de care acesta are nevoie.

S-ar putea aștepta o coloana adițională într-un anume tabel. Acest tabel ar putea fi prezent în toate rezultatele de calcul sau numai în unele din ele. Raportul XML ar putea atunci arăta mii de fișiere de rezultate care diferă de rezultatele așteptate. Fără instrumentul de evaluare al referințelor, persoana cu sarcina de a evalua rezultatele referințelor de calcul ar trebui să se uite la fiecare fișier și la fiecare diferență din acel fișier, pentru a fi sigur că diferențele sunt doar coloanele adiționale așteptate. După ce a luat o decizie în cea ce privește diferențele apărute el trebuie să seteze fiecare fișier cu valoarea statusului ”OK” dacă acestea sunt bune și ”not OK” în sens contrar. Dacă, de exemplu, există doar 500 de fișiere cu schimbările dorite și 504 fișiere arătând diferențe, 4 fișiere trebuie să fie lăsate și, de asemenea, toate fișierele care pot avea modificări suplimentare. Aceasta este o sarcină foarte obositoare și predispusă erorilor.

Următoarele trei scripturi Perl au ca rol prelucrarea rezultatului aplicației BearinX astfel încăt ca input pentru ”Instrumentul de evaluare al referințelor” să rezulte un fișier Xml.

calculateReference.pl

Fig. 1.3. Rezultatul scriptului Perl

compareReference.pl

Fig. 1.4. Rezultatul scriptului Perl

condense.pl

Fig. 1.5. Rezultatul scriptului Perl

Noul instrument va avea sarcina de a analiză toate diferențele și a le clasifica. Acesta va afișa coloanele suplimentare ca o singură categorie de diferență pentru toate fișierele, utilizatorul poate marca această schimbare ca fiind ”OK” pentru toate fișierele în care se află diferența.

Obiectivele lucrării de licență

După cum reiese din introducere, scopul acestei lucrări de licență este de a construi o aplicație desktop care să poată manipula rezultatele aplicației BearinX. Aceasta ar trebui să fie capabilă să lucreze cu fișiere Xml, trebuie să fie o aplicație ușor de utilizat oferind claritate informaților și un set de acțiuni pe care utilizatorul le are la dispoziție.

Disponibilitate

”Instrumentul de evaluare al referințelor” trebuie să aibă un design simplu cu comenzi explicite și fără orice ambiguitate astfel încât să poată asigura o accesibilitate bună pentru utilizator.

Flexibilitate

Datorită faptului că tehnologiile în domeniul informaticii evoluează foarte repede, aplicația trebuie construită astfel încăt să fie ușor de adaptat la noile schimbări . Designul ”Instrumentului de evaluare al referințelor” trebuie să fie modular și logica după care este scris codul care rulează în spate trebuie structurată într-un mod adecvat, astfel încât noile idei care pot să apară să fie ușor de implementat.

Simplitate și Rapiditate

Calitatea aplicației este dictată de simplitatea și viteza cu care ea răspunde nevoilor utilizatorului. ”Instrumentul de evaluare al referințelor” ar trebui să ofere utilizatorului un mod simplu de a determină diferențele constatate într-un fișier alături de alte informații utile de care utilizatorul ar putea avea nevoie pentru a face o decizie în cunoștiință de cauză cu privire la diferențele care apar în rezultatele aplicației BearinX.

Structura lucrării de licență

Documentația lucrării de licență cuprinde cinci capitole care sunt descrise pe scurt mai jos:

Capitolul 1 este un rezumat al aplicației și motivul pentru care aceasta a fost realizată și aplicabilitatea sa în lumea reală.

Capitolul 2 este un rezumat al tehnologiilor utilizate pentru a asigura proiectarea aplicației. Acesta descrie avantajele pentru utilizarea tehnologiei Windows Presentation Foundation, principalele controale utilizate în aplicație, împreună cu proprietățile pe care le dețin și în cele din urmă descrierea realizării interfeței grafice.

Capitolul 3 este despre tehnologiile utilizate în asigurarea funcționalității aplicației, detalii despre limbajul de programare C# și o scurtă prezentare despre scripturi în Perl. Limbajul de programare C# este suportul pentru ceea ce aplicația poate oferii user-ului și scripturile în Perl sunt utilizate pentru a obține informațiile necesare.

Capitolul 4 este o sinteză a tezei și expune punctele în care îmbunătățirile pot fi adăugate la aplicație.

Capitolul 5 este bibliografia.

Design de elemente grafice

Introducere

Fișierul XML cu diferențe poate fi deschis în cadrul unui browser web, dar acest lucru nu are posibilitatea de a oferi toate detaliile necesare pentru a decide dacă o diferența poate sau nu poate fi setată să fie „OK” sau „not OK”, aceste necesități se pot rezolva cu o aplicație desktop. Windows Presentation Foundation (WPF) a fost ales pentru crearea aplicației desktop. Principalul avantaj WPF este că acesta poate fi utilizat pe toate versiunile de Windows datorită bibliotecilor de rulare care sunt în mod implicit incluse.

Windows Presentation Foundation este un subsistem grafic pentru construirea de interfețe în Windows. Acesta a fost dezvoltat de Microsoft ca parte a .NET Framework 3.0 și a fost lansat pentru prima dată cu numele de "Avalon".

În programele software pentru calculator regulile de afaceri se rezumă la cum pot fi datele create, schimbate, stocate și afișate, aceasta parte a programului care codifică lumea reală, Windows Presentation Foundation urmărește să stabilească o graniță între interfața utilizatorului și logica de afaceri, asigurând o responsabilitate mai mare obiectelor software.

WPF lucrează cu Extensible Application Markup Language (XAML), care este, de asemenea, dezvoltat de Microsoft, acesta este un limbaj folosit pentru a descrie obiectele utilizate în aplicație, este ușor de citit de către oameni și instrumente pentru că arată ca un XML simplu. Limbajul XAML este folosit în aplicații ca WPF, Silverlight și WF (Windows Workflow Foundation), Windows Runtime XAML Framework și în mod extensiv in tehnologiile .NET Framework 3.0, .NET Framework 4.0.

Dintre WPF și WF a fost aleasă tehnologia WPF din următoarele motive:

WPF permite Databinding, o tehnică utilizată pentru a lega două surse de date împreună și menține datele sincronizate între ele;

Din cauza modului cum este proiectat XAML–ul interfețele create cu WPF îți mențin cu ușurință coerența la redimensionare, această sarcină poate fi implementată și în WF dar este mai dificil de programat.

Raport tehnic

Controale, proprietăți și evenimente în general

Designul în WPF se face prin scrierea de cod XAML. Dacă scrii o etichetă cu numele unui control, acesta este adăugat în fereastră, de asemenea unui control îi pot fi adăugate proprietăți și evenimente.

XAML este un limbaj ușor de utilizat și de înțeles. În timp ce scrii în interior unui tag al unui control XAML, un tooltip apare cu toate controalele disponibile pe care le puteți adăuga la controlul părinte. Elementele imbricate în interiorul altui obiect vor deveni copii obiectului respectiv.

Fig. 2.1. Tooltip controale

În timp ce scrii între tagurile unui control un tooltip apare cu toate proprietățile și evenimentele disponibile pentru controlul respectiv.

Fig. 2.2. Tooltip proprietăți

– reprezintă o proprietate;

– reprezintă o extensie de marcare;

– reprezintă un eveniment.

În contextul XAML, o proprietate este utilizată cu scopul de a adăuga funcționalități unui element, sintaxa unei proprietăți schimbându-se în funcție de aceasta.

În cele mai multe cazuri, evenimentele sunt utilizate în interfețe grafice, având rolul de a notifica aplicația în legatură cu schimbările efectuate de către utilizator. De exemplu: Un utilizator care dă click pe un buton va genera scrierea unei secvențe de cod corespunzătoare evenimentului de Click al butonului.

În situația în care elementul selectat al tooltip-ului este un eveniment, tooltip-ul și opțiunile disponibile vor fi reprezentate grafic astfel:

Fig. 2.3. Tooltip evenimente

În momentul creării unui nou eveniment, Visual Studio va genera scrierea unui handler de eveniment, metodă ce urmează a fi definită.

Dacă în cadrul aplicației există și alte handlere de evenimente, denumirile acestora vor fi vizibile în tooltip, dezvoltatorul având opțiunea de a crea un nou handler de eveniment sau de a folosi unul existent.

Fig. 2.4. Tooltip evenimente

O extensie de marcare este de fapt o instanțiere de clasă, dar scrisă între acolade {} în loc să se folosească notația elementului XAML. După crearea instanței și inițializarea oricărei proprietăți, XAML solicită metoda ProvideValue a extinderii marcate care returnează o valoare reală.

Spații de nume în XAML

Modul de funcționare al spațiilor de nume în XAML este similar modului de funcționare al CLR-ului notifica aplicația în legatură cu schimbările efectuate de către utilizator. De exemplu: Un utilizator care dă click pe un buton va genera scrierea unei secvențe de cod corespunzătoare evenimentului de Click al butonului.

În situația în care elementul selectat al tooltip-ului este un eveniment, tooltip-ul și opțiunile disponibile vor fi reprezentate grafic astfel:

Fig. 2.3. Tooltip evenimente

În momentul creării unui nou eveniment, Visual Studio va genera scrierea unui handler de eveniment, metodă ce urmează a fi definită.

Dacă în cadrul aplicației există și alte handlere de evenimente, denumirile acestora vor fi vizibile în tooltip, dezvoltatorul având opțiunea de a crea un nou handler de eveniment sau de a folosi unul existent.

Fig. 2.4. Tooltip evenimente

O extensie de marcare este de fapt o instanțiere de clasă, dar scrisă între acolade {} în loc să se folosească notația elementului XAML. După crearea instanței și inițializarea oricărei proprietăți, XAML solicită metoda ProvideValue a extinderii marcate care returnează o valoare reală.

Spații de nume în XAML

Modul de funcționare al spațiilor de nume în XAML este similar modului de funcționare al CLR-ului (Common Language Runtime). Un spațiu de nume în XAML se mapează pe un spațiu de nume CLR, declararea acestuia în XAML fiind similară directivei “using” din C#.

În mod predefinit, WPF utilizează propriul spațiu de nume, acesta fiind reprezentat în XAML cu ajutorul prefixului X: (utilizat pentru cuvintele cheie specifice XAML).

Cu toate acestea, XAML utilizează un spațiu de nume specific, care conține cuvinte cheie precum Type, Null, Name, etc.

Diferența dintre un spațiu de nume WPF și un spațiu de nume XAML este determinată de către prefix. În mod normal, pentru prefix se folosește sintaxa “x:”, însă aceasta nu este obligatorie.

De asemenea, există posibilitatea adăugării unui spațiu de nume propriu. Această operație se realizează prin introducerea sintagmei “xmlns:<prefix>=”, un tooltip conținând toate spațiile de nume cunoscute în proiect.

Fig. 2.5. Spații de nume in XAML

Window

În momentul creării unui nou proiect WPF, Visual Studio generează cod C# și XAML, corespunzător inițializării unui control de tip Window (unei ferestre):

Fig. 2.6. Sintaxă ”Window”

O fereastră în WPF este controlul principal care conține restul obiectelor conținute în tag-urile corespunzătoare. Acest control are rolul de a menține design-ul grafic al aplicației și de a crea relația dintre utilizatori și date.

Controalele folosite într-o aplicație pot fi folosite cu mai multe scopuri, iar controlul ”window” nu face excepție de la acest lucru. Printre proprietățile acestora se numără și ”Resources” și ”CommandBinding”, acestea fiind folosite des în realizarea ”Instrumentului de evaluare al referințelor”.

Într-o aplicație WPF, datele pot fi stocate drept resurse în trei moduri:

local pentru un control;

local pentru o fereastră;

global pentru întreaga aplicație.

Atunci când este creată o resursă, atributul ”x:Key” trebuie să fie asignat pentru a putea fi mai apoi folosit în cadrul aplicației. În urma acestei atribuiri, accesul la resursă se poate face prin extensia markup ”StaticResource” sau prin extensia markup ”DymanicResource”, diferența dintre cele două fiind faptul că resursele statice vor fi încărcate o singură dată, atunci când se încarcă XAML-ul iar schimbările aduse resursei nu se vor reflecta în aplicație, în timp ce resursele dinamice iau în calcul aceste schimbări făcute pe parcurs.

O altă proprietate ce se poate folosi pentru o fereastră este ”CommandBindings”.

Sintaxa pentru aceasta poate fi observată în figura 2.7.

Figura 2.7. Sintaxa ”CommandBindings”

Un ”CommandBinding” permite elementelor cărora îi este aplicat manevrarea de comenzi. Această proprietate următoarele atribute care se setează de către programator:

Command

CanExecute

Executed

Menu

Controlul ”Menu” este foarte simplu de folosit, permițând integrarea cu ușurință a unui meniu în cadrul interfeței și este foarte folositor; putem observa că majoritatea aplicațiilor care se folosesc astăzi dispun de un astfel de meniu. În mod uzual, prin intermediul acestui control se oferă acces la toate acțiunile principale ale aplicației, acțiunile fiind divizate printr-un criteriu comun.

Figura 2.8. Controlul ”Menu”

Elementele unui meniu pot fi simple, pot avea imagini, se pot bifa sau debifa și pot exista separatori între două linii de meniu. Se pot adăuga shortcut-uri (scurtături) unui element din meniu prin folosirea caracterului ”underscore” (_) poziționat în fața caracterului pe care îl vom folosi drept „shortcut” corespondent elementului.

Grid

Un control ”grid” este similar cu un tabel, în sensul că aranjează toate controalele copii în forma unei structuri tabelare formată din linii și coloane. Grid-ul este format în mod default din o coloană și o linie, iar adăugarea de mai multe linii se face prin adăugarea unui nou ”RowDefinition” pentru fiecare linie nouă dorită în cadrul proprietății ”RowDefinitions” a gridului, adăugarea de coloane fiind similară, respectiv adăugarea unui ”ColumnDefinition” în cadrul ”ColumnDefinitions”.

La definirea de linii și coloane folosind ”RowDefinition” și ”ColumnDefinition”, se pot seta o serie de trăsături printr-o serie de proprietăți ce sunt puse la dispoziție. Spre exemplu, setarea dimensiunii este realizată prin folosirea proprietăților ”Height” și ”Width”, iar pentru aceste proprietăți avem o serie de opțiuni:

atribuirea unei dimensiuni fixe prin valori duble

folosirea cuvântului cheie ”auto” pentru a da de înțeles că dimensiunea se calculează în funcție de dimensiunile controalelor copii

folosirea asteriscului (*) pentru a semnala că dimensiunea va fi tot spațiul ce se află la dispoziție în grid pe verticală/orizontală

În cazul coloanelor, ajustarea dimensiunii unei coloane se face astfel: pentru coloanele cu o lățime fixată vor ocupa spațiul desemnat de acea dimensiune, cele cu lățime automată vor ocupa spațiul necesar pentru a plasa controalele copii în cadrul coloanei. Spațiul rămas este alocat coloanelor ce folosesc * în definirea lățimii. Suma tuturor acestora (*) este calculată pentru împărțirea lățimii rămase disponibilă; divizând lățimea rămasă la numărul de * vom obține lățimea unei astfel de coloane.

Pentru a selecta linia sau coloana unde urmează să fie plasat un control copil, se folosește proprietatea ”Grid.Row”, respectiv ”Grid.Column” a acestuia. ”Grid.RowSpan/ Grid.ColumnSpan” este proprietatea folosită pentru plasarea unui copil pe o suprafață cu înălțimea/lățimea echivalentă mai multor linii/coloane.

DataGrid

Controalele ”DataGrid” sunt foarte folosite în cadrul aplicațiilor datorită capacității acestora de a afișa informații într-o manieră rapidă și ușoară.

Exemple de proprietăți sau evenimente care pot fi folosite pentru un astfel de control sunt: ”AutoGenerateColumns” specifică dacă DataGrid-ul ar trebui sau nu să genereze coloane pe baza datelor, o coloană pentru fiecare proprietate a unui element ce se află pe o linie sau, în cazul în care utilizatorul definește propriile coloane, DataGrid-ul va conține o coloană pentru fiecare dintre proprietățile atașate coloanelor definite manual.

”ItemsSource” definește sursa datelor pentru popularea DataGrid-ului. ”Xpath” este folosit pentru limitarea itemilor prin preluarea de la sursă numai a celor specificați de către ”Xpath”; de exemplu, XPath=“/Shop/Products/Product[@Stock > 0]” va limita itemii numai la acele tipuri de produse care au proprietatea Stock mai mare decât 0 și care aparțin unui obiect ”Product”, care la rândul lui aparține unui ”Shop”.

”ContextMenu” este folosit pentru crearea unui meniu context, acesta apare numai când utilizatorul interfeței dorește

Figura 2.9. Proprietatea ”ContextMenu”

Evenimentul de ”sorting” permite selectarea criteriului după care se face sortarea datelor din DataGrid. Sortarea se face prin apăsarea unui click pe header-ul DataGrid-ului.

GridSplitter

Un ”GridSplitter” este un control folosit pentru a redistribui spațiul între coloanele sau liniile unui grid. Spre exemplu, un ”GridSplitter” plasat pe a doua linie și setat cu valoarea ”PreviousAndNext” într-un grid cu comportament de redimensionare ce conține trei linii care se întind pe lățimea cumulată a tuturor coloanelor ar putea fi folosit pentru a redistribui spațiul între prima și ultima linie. Proprietățile care determină natura unui ”GridSplitter” sunt ”ResizeDirection” și ”ResizeBehaviour”.

”ResizeDirection” poate lua una din trei valori:

”rows”: redimensionarea liniilor controlului

”columns”: redimensionarea coloanelor controlului

”auto”: redimensionarea fie a liniilor, fie a coloanelor, direcția fiind dată de layout-ul splitter-ului

”ResizeBehaviour” poate lua una din patru valori:

”BasedOnAlignment”: spațiile sunt redistribuite în funcție de proprietățile ”HorizontalAlignment” și ”VerticalAlignment” ale GridSplitter-ului. Spre exemplu, să considerăm un GridSplitter aliniat vertical în stânga și având direcția de redimensionare bazată pe coloane. GridSplitter-ul va redistribui spațiul între coloana aflată în stânga splitter-ului și coloana corespunzătoare acestuia

”CurrentAndNext”: spațiul este redistribuit între linia sau coloana splitter-ului și următoarea linie/coloană, următoarea însemnând de fapt linia/coloana aflată imediat următoare în jos/dreapta în cazul redistriburii pe linii/coloane

”PreviousAndCurrent”: spațiul este redistribuit între linia sau coloana splitter-ului și anterioara linie/coloană, următoarea însemnând de fapt linia/coloana aflată deasupra/în dreapta în cazul redistriburii pe linii/coloane

”PreviousAndNext”: folosită pentru un splitter care redistribuie spațiul între linii, liniile aflate deasupra/dedesubtul splitter-ului sunt cele al căror spațiu este redistribuit, similar pentru coloane (coloana din stânga și coloana din dreapta splitter-ului)

XmlDataProvider

”XmlDataProvider” furnizează un mod ușor pentru folosirea de fișiere XML prin legarea datelor la un nod al unui arbore XML.

Există două moduri de utilizare a unui ”XmlDataProvider” ca resursă:

Referința ”XmlDataProvider” către un fișier extern

Încorporarea datelor în textul intern al unui ”XmlDataProvider”, text aflat în cadrul tag-ului ”<x:XData>”

Figura 2.10. Exemplu ”XmlDataProvider”

Interfața grafică a aplicației ”Instrument de evaluare al referințelor”

Atunci când ne gândim la designul unei aplicații, trebuie să vizualizăm GUI–ul (Graphical User Interface) aplicației, un design ar trebui elaborat de către user–ul care are nevoie de aplicația respectivă. După ce proiectarea GUI-ului a fost decisă, ar trebui să fie luată în considerare partea de logică a aplicației.

În WPF când un proiect nou este creat se generează o clasă Window numită MainWindow. În XAML designul la o fereastră inițială începe cu eticheta de Window care cuprinde toate celelalte etichete cu atributele generale ale ferestrei. Fereastra va conține, de asemenea, un control imbricat de tipul Grid care va fi gridul principal și va conține toate controalele care se vor adăuga pe parcurs.

Primul control care ar putea fi adăugat este controlul Menu deoarece structura aplicației este deja cunoscută.

Fig. 2.11. Controlul ”Menu”

În exemplu de mai sus atributele controlului Menu sunt folosite să seteze poziția meniului, după care primul item al meniului este MenuItem cu proprietatea header setată la _File, linia de subliniere este folosită doar pentru a marca o scurtătură, când user-ul dă click pe itemul din meniu cu numele de File se deschide un sub meniu cu cele trei itemuri definite.

Sub meniu este un control ToolBar care conține butoane folosite pentru comenzi ca Open,Save,Commit,Undo. Aceste comenzi sunt cele mai folosite. Pentru că aceste butoane au o imagine in loc de text, proprietatea ToolTip este setată să informeze user-ul ce rol au butoanele, ToolTip–ul apare doar când cursorul este poziționat deasupra butonului.

Fig. 2.12. Controlul ”ToolBar”

Proprietatea Command care este în meniu și în bara de instrumente are valoarea ApplicationComands.Open, această comandă este definită în proprietatea ferestrei CommandBindings.

Fig. 2.13. Proprietatea ”ComandBindings”

Același lucru este făcut și pentru comenzile de Close, Help, Save, și Undo.

Controalele utilizate pentru afișarea datelor au fost create astfel încât în partea stângă a ferestrei să fie afișate detaliile despre diferențe și în partea dreaptă a ferestrei să fie indicate detalii despre fișierele în care se află diferențele. Rolul său a fost de a grupa fișierele după o diferență comună.

Fig. 2.14. Instrumentul de evaluare al referințelor

Dar pentru că un fișier poate conține mai multe diferențe și o diferență poate aparține mai multor fișiere, o nouă problemă a apărut: și anume de a găsi toate diferențele care aparțin unui singur fișier. Acest lucru este greu de realizat deoarece un utilizator ar trebui să selecteze orice diferență și să verifice dacă fișierul dorit are această diferență. O nouă viziune a trebuit să fie implementată, cea care va afișa toate diferențele dintr-un fișier selectat.

Pentru a asigura o imagine mai clară a diferențelor, un al treilea control de tipul DataGrid a fost adăugat pentru a afișa diferențele dintr-un fișier selectat.

Ultimul design graphic al aplicației ”Intrumentul de evaluare al referințelor” este următorul:

Fig. 2.15. Instrumentul de evaluare al referințelor

Pentru a adăuga noul control DataGrid, structura gridului principal este modificată astfel încât noul control DataGrid este plasat sub controlul DataGrid care afișează fișierele. Modificările au fost făcute în XAML și procesul de adăugare a noului control este prezentat pas cu pas.

În primul rând structura gridului principal a fost extinsă, numărul de rânduri a fost crescut cu doi, unul pentru că poziția celui de al treilea DataGrid ar trebui să fie în partea dreaptă jos și celălalt pentru a fi pus un control GridSplitter între cele două controale care afișează datele.

Fig. 2.16. Structura gridului principal

Proprietățile width și height nu sunt setate la o valoare fixă, de exemplu primul rând are valoarea proprietății height setată la auto, ceea ce înseamnă că înălțimea rândului va fi determinată de elementele care vor fi plasate pe acesta.

Fig. 2.17. Controlul ”Menu”

În acest caz, meniul este pe primul rând (Grid.Row = "0"), astfel încât înălțimea primului rând va fi de 25 de unități. Dacă mai multe controale ar fi plasate în același rând, fiecare cu o valoare diferită a proprietății height atunci înălțimea rândului va fi înălțimea celui mai înalt element care va fi plasat în el.

Avem trei rânduri cu height = "Auto" și două cu height = "*", asta înseamnă că dacă adunăm unitățile celor două care au setată proprietatea height la auto, pentru restul cu proprietatea height setată cu * vor avea înălțimea egală cu diferența dintre înalțimea ferestrei și suma înălțimilor celor cu proprietatea height setată cu auto împărțită la numărul de rânduri care au proprietatea height setată la Auto.

Următorul pas a fost de a crea un GridSplitter care să redistribuie dimensiunea între cele două controale DataGrid:

Fig. 2.18. Controlul ”GridSplitter”

Proprietățile Grid.Column și Grid.Rows sunt egale cu 2, respectiv 3 pentru că poziția controlului GridSplitter este între controlul DataGrid care afișează fișierele și noul control DataGrid. De asemenea proprietatea ResizeBehavior este setată la valoarea PreviousAndNext. Din cauza plasării unui ComboBox deasupra noului control DataGrid și pe baza valorii pe care o are proprietatea ResizeBehaviour a controlui GridSplitter, splitter-ul va lua in considerare controlul ComboBox ca o consecință următorul pas a fost să fie adăugat un nou control Grid imbricat în controlul principal de tipul Grid care să conțină controalele noi: ComboBox și DataGrid; astfel încât controlul GridSplitter va lua în considerare noul grid ca fiind un întreg,

Noul control Grid are o structură destul de simplă, conține două rânduri, pe primul este plasat controlul ComboBox iar pe al doilea rând este plasat controlul DataGrid.

Controlul ComboBox are rolul de a limita datele afișate de către controlul DataGrid în funcție de valoarea câmpului status. Combobox are patru elemente: primul este folosit pentru a arăta toate modificările și următorii trei sunt utilizați pentru a afișa doar elementele care au valoarea statusului: “open”, “OK”, “not OK”.

Fig. 2.19. Controlul ”ComboBox”

Fiind ușor să fie populate cu date, controalele de tipul DataGrid sunt probabil cea mai bună metodă de a afișa informații. Structura la al treilea control de tipul DataGrid este similară cu cea a primului control DataGrid, din partea stângă a ferestrei deoarece ambele sunt utilizate pentru a afișa diferențele. Diferența dintre cele două fiind coloanele afișate, aceasta afișează cinci coloane: starea (status), diferența relativă pozitivă (posRelDiff), diferența relativă negativă (negRelDiff), diferența absolută (absDiff) și numele diferenței (change).

Fig. 2.20. Controlul ”DataGrid”

Proprietatea AutoGenerateColumns este setată cu valoarea “false”, asta înseamnă că coloanele nu sunt generate automat atunci când acestea sunt legate de date, dar ele ar trebui să fie create în mod explicit în codul WPF. Evenimentul Sorting are rolul de a sorta coloanele de diferite tipuri (numerice, șiruri de caractere).

Meniul contextual apare pe GUI la click dreapta pe rândul selectat din controlul DataGrid.

Evenimentul de Click implementat în meniul face aplicatia mai ușor de folosit pentru utilizatori, pentru că este mai rapid pentru user să facă clic dreapta și să aleagă o acțiune în loc de a merge în meniul principal și apoi să selecteze acțiunea de acolo. După ce utilizatorul a verificat diferența poate alege din meniul contextual pentru a seta starea (status) ”OK” sau ”not OK”.

Fig. 2.21. Proprietatea ”ContextMenu”

Datele care sunt încărcate în controalele DataGrid provin din două fișiere XML externe. Marcajul de extindere StaticResources utilizează valoarea atributului x: Key a controlului XmlDataProvider și proprietatea XPath ca o interogare care returnează valoarea care este indicată în cale din documentul XML.

Fig. 2.22. Proprietatea ”ItemSource”

Deoarece coloanele din controlul DataGrid nu sunt automat generate, codul pentru a le genera trebuie să fie scris manual:

Fig. 2.23. Exemplu coloană din DataGrid

Stilurile sunt utilizate pentru a stabili proprietățile fiecărui obiect care are atributul Style.

Unei proprietăți îi este dat o valoare cu ajutorul controlului Setter între tagurile atributului Style. O coloană care aparține controlului DataGrid poate seta stilul pentru toate celulele care se găsesc pe acea coloană.

Un următor pas în procesul de proiectare a aplicației a fost de a adăuga o fereastră nouă care permite configurarea parametrilor pentru scriptul Perl compareReference.pl. Deși are un design simplu, rolul său este importanța pentru aplicație, deoarece utilizatorul va ajusta detaliile pentru compararea și condensare fișierelor efectuate de scriptul Perl.

Acești parametrii devin de configurare pentru aplicație, ei pot fi setații în fereastra de setări (Settings Window) și apoi salvați într-un fișier XML. Dacă parametrii lipsesc din fișierul XML, sunt încărcați în fereastra de setări cu valori implicite și sunt adăugați în fișierul XML.

Fig. 2.24. Fereastra de setări

Capitolul 3. Logica de funcționalitate a aplicației ”Instrument de evaluare al referințelor”

3.1. Introducere

Limbajul de programare C# a fost dezvoltat de către o echipă condusă de Anders Hejlsberg în Ianuarie 1999 în cadrul inițiativei .Net a Microsoft. A fost aprobat de către Ecma (European Computer Manufacturers Association – o organizație internațională privată, non-profit ce promovează standarde organizaționale pentru sisteme de informații și comunicare) și ISO (International Organization for Standardization – o organizație internațională a standardelor compusă din reprezentativi din multiple organizații dedicate standardelor naționale). Scopul acestuia a fost să dea viața unui limbaj de programare orientat pe obiecte simplu și modern.

Originar C# urma să se numească “Cool”, reprezentarea prescurtată a "C-like Object Oriented Language”, dar compania Microsoft a optat pentru a schimba numele din motive de originalitate.

3.2. Suport tehnic

3.2.1. Punct de intrare

Un punct de intrare reprezintă locul unde controlul începe execuția unui program. Acesta conține funcția „main” care este apelată atunci când un program își începe execuția.

Orice aplicație ar trebui să conțină un punct de intrare, iar numărul acestora poate fi egal cu numărul de clase pe care le conține aplicația deoarece toate ar putea conține o astfel de metodă. Orice funcție „main” ar putea fi aleasă ca punct de intrare.

În WPF un punct de intrare (main) este generat în timpul build-ului și poate fi găsit in cadrul App.g.i.cs în fișierul de configurare localizat în obj/Debug.

3.2.2. Suportul documentației Xml

În cadrul limbajului de programare C#, dacă o linie de cod începe cu simbolul “///” și sub acesata este situată declarația unei clase, delegate, interfețe, membrul unei clase sau un așa numit „namespace”, atunci este cert că există documentație. Utilizând protocolul Xml, avem posibilitatea de a divide documentația noastră în diferite câmpuri răspândite în cadrul codului sursă. În meniul “Tools” din platforma Visual Studio, opțiunea “Build Comment Web Pages” ne permite să creăm pagini de documentație.

În momentul în care o metodă este apelată va apărea o fereastră de extensie ce conține documentația metodei respective. Textul scris în caractere îngroșate reprezintă parametrul curent ce trebuie introdus.

3.2.3. Definiția unui obiect

Programarea orientată pe obiecte presupune că toate instrucțiunile sunt trimise și executate prin intermediul obiectelor. Acest concept reprezintă fundamentul aplicațiilor software în .NET.

Un obiect software reprezintă o entitate căruia îi asociem un ciclu de viața, caracterizat cu ajutorul a trei atribute fundamentale : identitate, stare și comportament. În cadrul ciclului de viață al acestuia, starea i se schimbă ca rezultat al comportamentului și al reacțiilor impulsurilor și evenimentelor exterioare. Esențial este că acesta își păstrează identitatea proprie pe tot parcursul ciclului său de viață.

Starea unui obiect depinde de gruparea tuturor atributelor pe care acesta le deține și este reprezentată cu ajutorul unui set de valori, la o anumită valorare temporală. Chiar dacă starea unui obiect variază, structura stării rămâne invariabilă.

Comportamentul unui obiect include toate acțiunile posibile cât și reacțiile sale la toate impulsurile și evenimentele exterioare. Acesta poate fi influențat de către starea obiectului cât și schimbările valorilor atributelor de stare ale acestuia.

Identitatea este o proprietate ce caracterizează propria existență a unui obiect, ceea ce înseamnă că orice obiect trebuie să aibă un nume unic.

În cadrul limbajului c# tipul unui obiect poate fi dată, string, numeric sau acțiune a unei clase ce a căpătat comportamentul unui obiect.

3.2.4. Serviciile unui obiect

În momentul în care creăm un obiect avem posibilitatea de a-i utiliza serviciile prin intermediul operatorului “dot”. Acestea presupun un set de metode și proprietăți care numai un obiect le poate accesa. Metodele ce pot fi apelate sunt definite precum funcții și reprezintă capacitatea unui obiect de a executa anumite operații, iar proprietățile sunt intermediarii prin care se poate accesa starea unui obiect.

3.2.5. Proprietățile de incluziune ale C#

O proprietate este un atribut al unui obiect și este definită de către metodele sale de “get” și ”set” :

Metodele de tip “get” permit acces de citire

Metodele de tip “set” permit acces de scriere

Metodele de “get” pot fi declarate fără corp și sunt utilizate ca scurtătură , iar funcțiile de “get” și ”set” au rolul de intermediari de acces standard. Următoarele exemple au același rezultat.

O proprietate căreia îi lipsește metoda de “set” devine prin definiție read-only.

Proprietatea de suprafață a unui dreptunghi este așa numită “read-only”, ceea ce semnifică că acesta poate doar fi citită nu și modificată. Din punct de vedere logic, nu are sens ca utilizatorul sa dețină capacitatea de a seta această valoare deoarece, acest lucru implică modificarea valorilor laturilor respectivului dreptunghi și totodată există multiple combinații ale laturilor unui dreptunghi care pot avea ca rezultat aceeași arie.

3.2.6. Spații de nume

Cuvântul cheie “namespace” este utilizat pentru declararea unui set de obiecte relatate.

Acestea sunt utilizate pentru identificarea tipurilor unice, fapt ce ajuta la organizarea aplicațiilor .NET și totodată organizarea externă cu ajutorul căreia un program va fi inclus atât intern cât și extern.

3.2.7. Variabile în cadrul .NET

În cadrul limbajului de programare C#, fiecare variabilă, constantă sau expresie utilizată pentru evaluarea tipului face ca limbajul să fie orientat pe tipul unei variabile. Semnătura unei metode specifică tipul date returnate precum și tipul fiecărui parametru, lăsând nici urma de îndoială asupra parametrilor sau tipului de date returnate.

Framework-ul .NET definește următoarele tipuri de date:

tipuri numerice

clase de tip fișiere de sistem

conexiuni de rețea

colecții de vectori

date

Utilizatorul are totodată posibilitatea de a defini tipuri proprii de date ce răspund la cererile domeniului unui program.

În cadrul programării orientate pe obiecte există trei tipuri logice de date:

obiect adevărat

obiect valoare

obiect chestionabil

În .NET există trei tipuri de variabile:

tipul referință (necesită definirea sub formă de clasă)

tipul valoare (necesită definirea ca structură sau enum)

suport pentru tipul pointer (sintaxa limbajului C este susținută)

Sistemul unificat este specific pentru limbajul de programare C#. În cadrul .NET fiecare tip de dată este direct sau indirect derivat din clasa Obiect (clasa de bază în .NET ) deoarece valoarea fiecărei variabile poate fi tratată precum un obiect.

În limbajul C# inițializatorul specific este constructorul al cărui scop este de a asigura abilitatea de a delega task-uri de la un constructor la altul.

În exemplul prezentat ulterior, clasa Rectangle are doi constructori. Primul setează ambele laturi ale dreptunghiului, cel de-al doilea poate fi utilizat pentru a instanția pătrate, având un singur parametru de intrare și presupune că lungimea și lățimea au valori egale.

Constructorul cu un singur parametru de intrare îl va apela pe cel cu doi parametri, trimițând acestuia de doua ori aceeași valoare.

3.2.8. Principii generale ale moștenirii

Moștenirea este o relație ce apare între clase. Atunci când o clasă moștenește o altă clasă, aceasta își asumă toate funcțiile, proprietățile și variabilele acesteia. Clasa inițială este atunci numită super-clasă, iar pe cea derivată o vom numi sub-clasă. Super-clasa conține toate caracteristicile generale iar caracteristicile sub-clasei au un caracter mai particular.

Există posibilitatea ca sub-clasa să aibă rol de super-clasa pentru o alta clasă, dând astfel naștere la o așa numită ierarhie.

Obiectul unei sub-clase este considerat ca fiind totodată obiect al super-clasei.

Există cinci nivele de accesibilitate reprezentate cu ajutorul modificatorilor de acces:

public, accesul este liber tuturor

private, accesul este restricționat în interiorul clasei

protected, accesul este permis din interiorul clasei respective cât și din clasele derivate.

protected internal, protejat in interiorul propriului ansamblu

internal, este accesibil doar din interiorul ansamblului.

Acești membrii combinați sunt numiți și interfață a clasei. Ei sunt vizibili de către persoana care utilizează clasa în cauză. În general metodele și proprietățile unei clase ar trebui restricționate pentru accesul strict necesar și nu ar trebui să fie incluse lucruri care nu au legătură cu funcționalitatea internă a clasei.

Membrii privați nu sunt vizibili pentru utilizator.

Membrii protejați (protected) pot fi accesați cu ajutorul metodelor de “get” și ”set” într-un context în care nu este necesar ca utilizatorul sa aibă această posibilitate, dar ea rămâne disponibilă pentru obiectele derivate ale clasei.

Moștenirile multiple derivă din ierarhia de clase. O ierarhie este un aranjament de clase unde acestea sunt reprezentate ca fiind deasupra, dedesubt sau pe același nivel cu alte clase.

3.2.9. Polimorfismul

În cadrul programării orientate pe obiecte, polimorfismul este generalizarea grupurilor de obiecte oferindu-le acestora o interfață comună. Interfața utilizată în polimorfism trebuie să conțină minimul de metode fără implementarea fizică care trebuie să îndeplinească anumite funcții dar nu se cunoaște exact cum.

Există două forme de polimorfism:

polimorfism cu interfață

polimorfism prin moștenire

Polimorfismul cu interfață

conține metode cu semnătură identică dar care sunt definite în clase diferite

metodele sunt supraîncărcate în aceeași clasă

Polimorfism prin moștenire

Este considerat singurul polimorfism real și are legătură cu funcționalitatea virtuală.

3.2.10. Tratarea excepțiilor

Tratarea excepțiilor reprezintă procesul de a răspunde la anumite situații care se abat de la fluxul normal de funcționare al execuției unui program.

Situații anormale precum: erori care apar la scrierea sau citirea dintr-o anumită locație din memorie, accesul către o baza de date, lipsa răspunsului unui obiect server când se dorește comunicarea cu acesta, erori ce pot apărea la calculul și utilizarea datelor, probleme ce apar când se utilizează dispozitive externe, etc. Toate aceste probleme pot fi tratate cu ajutorul excepțiilor, astfel că în momentul în care are loc o situație anormală, gestionarul de excepții (handler) lansează un astfel de mesaj.

În .NET originea excepțiilor este mediul de execuție și executare a unui program. Modelul de gestiune al excepțiilor are baza pe niște fragmente protejate de cod și obiecte de tip excepție.

Runtime-ul .NET permite gestiunea obiectelor de tip excepție cu ajutorul instanțelor clasei Exception sau instanțe ale claselor derivate din aceasta.

Putem utiliza trei tipuri de gestionari de excepții (exception handlers):

finally hangler

fault handler

type-filtered handler

Gestionarea excepțiilor:

try-catch;

try-finally;

try-catch-catch-finally.

În exemplul cu dreptunghiul, o excepție va fi aruncată când aplicația va atenta să atribuie o valoare negativă laturilor acestuia și va fi însoțită de un mesaj de avertisment adecvat.

Excepțiile particulare pot fi create ca și clase derivate ale Exception. Spre exemplu o instanță a clasei ScalableException este aruncată atunci când factorului de scară i se atribuie valori negative. Rolul acestor excepții particulare este de a trimite informații ce nu pot fi trimise utilizând doar clasa Exception, cum ar fi scara factorului pe care proprietatea Scale urma să o seteze.

Excepțiile sunt aruncate cu ajutorul unui bloc de tip try-catch. Acestea sunt prinse în interiorul acestor segmente de cod care conțin parametrii ce pot fi asignați tipului de excepție care a fost aruncată. Îndată ce o excepție a fost prinsă de către o serie de mai multe blocuri “catch” aceasta va fi atribuită primului întâlnit în ordine descendentă. Blocul “finally” este apelat indiferent dacă a avut loc sau nu o excepție.

3.2.11. Fire de execuție și procese

În mod tradițional aplicațiile de tip consolă, WPF sau alte forme de aplicații Windows, sunt aplicații cu un singur fir de execuție (thread) și toate instrucțiunile conținute de către acest tip de aplicații sunt executate secvențial în funcție de cum au fost ele înșiruite în mod automat de către CLR (Common Language Runtime). Ideea de a avea multiple fire de execuție reprezintă conceptul de a distribui mai multe segmente de cod (instrucțiuni) pe diferite procesoare.

Firele de execuție au trei proprietăți principale:

îi dau programului posibilitatea să realizeze procesare concurentă

Framework-ul .NET numit System.Threading face lucrul cu fire de execuție ușor

firele de execuție împart resursele aplicației în funcție de necesități

În majoritatea situațiilor întâlnite, firele de execuție sunt utilizate pentru a economisi timp. Din punct de vedere al programatorului o aplicație cu multiple fire de execuție are un fir principal, care este creat de către CLR și este capabil să lanseze la rândul său unul sau mai multe fire de execuție in felul următor.

În interiorul parantezelor este apelată funcția ce urmează să fie executată de firul “t” creat, iar cu ajutorul comenzii acesta începe execuția în timp ce firul principal execută în continuare alte instrucțiuni. Din acest exemplu putem să observăm diferența dintre o aplicație cu un singur fir și o aplicație ce rulează pe mai multe fire de execuție:

un fir de execuție unic presupune ca aplicația să secvențial instrucțiunile parcurse

multiple fire de execuție, presupune ca sarcinile sunt executate simultan pe fire diferite și are ca rezultat un timp necesar de lucru redus.

În proiectele de scară amplă, utilizarea multiplelor fire de execuție este necesară pentru a economisi timp și a preveni așteptarea utilizatorului pentru rezultate diferite.

Un obiect de tip fir de execuție are o multitudine de proprietăți și metode, dar cele mai importante dintre acestea sunt start, join și sleep. Metoda “join” este utilizată pentru a înștiința alt fir de execuție să aștepte finalizarea execuției firului curent, iar metoda “sleep” este utilizată pentru a îngheța temporar execuția unui thread pentru o perioadă specificată de timp.

Când asignam task-uri diferitelor fire de execuție este necesar un plus de atenție pentru a nu intercala instrucțiunile dintr-un thread diferit.

3.2.12. Xml

Pentru a lucra cu Xml, în primul rând trebuie adăugate spații de nume (namespace-uri) System.Xml ce oferă elemente cu denumiri unice, într-un document Xml.

Cele mai importante clase utilizate sunt:

XmlDocument;

XmlNode;

XmlAttributes;

XmlNodeList.

Cu ajutorul acestor clase este foarte ușor de modelat și lucrat cu fișiere XML.

Cele mai utile proprietăți și metode sunt următoarele:

Attributes;

ChildNodes;

FirstChild;

ParentNode;

AppendChild;

CreateAttribute;

SelectNodes;

Logica operațională

Introducere

Perl este un acronim pentru Practical Extraction and Reporting Language. A fost proiectat de către Larry Wall în 1987 pentru a fi o unealtă de scriere a unor programe de procesare a rapoartelor în sistemul de operare UNIX. Perl constă într-o gamă de limbaje de nivel înalt, cu un scop general, interpretate și dinamice, iar ultima versiune este Perl 6.

Limbajul Perl oferă posibilitatea de prelucrare a fișierelor text fără limitare a lungimii datelor arbitrare, așa cum au aplicațiile cu linii de comandă Unix. Perl 5 a câștigat popularitate târziu în 1990 ca un CGI (Common Gateway Interface), limbaj de programare datorat Regex (expresie regulată) și capacității sale de a divide șirurile de caractere. Multe alte caracteristici ale limbajului Perl sunt împrumutate de la alte limbaje de programare cum ar fi C, AWK, sed și shell scripting (sh).

Raportul tehnic

Pentru a preveni deteriorarea datelor senzitive cu un program scris in Perl, este indicat să fie utilizată comanda "use strict" la începutul oricărui program. O comandă asemănătoare cu "use strict" se numește pragma. Pragma-urile sunt instrucțiuni trimise către interpretorul Perl-ului, ce schimbă comportamentul programului în timpul rulării.

"Use strict" realizează două lucruri prin care îngreunează scrierea unui software greșit:

determină programatorul să-și declare toate variabilele;

îngreunează interpretorul Perl să înțeleagă greșit intențiile programatorului atunci când sunt utilizate funcții (sub-uri).

Dacă este necesar în program doar un tip sau două de reguli stricte, acestea trebuie enumerate în pragma "use strict" sau o pragma "no strict" poate fi utilizată pentru a opri una sau toate regulile stricte ce au fost activate mai devreme.

Exemplu:

use strict 'vars'; – solicită variabilele care trebuie declarate;

no strict 'vars'; – face revenirea la regulile inițiale de declarare a variabilelor;

use strict 'subs'; – Perl are încredere în barewords (de exemplu: operatori ce returnează identificatori de fișiere);

no strict; – oprește funcționarea tuturor regulilor.

O metodă de a fi sigur de corectitudinea programului este să fie folosită instrucțiunea "use strict vars", ceea ce înseamnă că o variabilă trebuie declarată înainte de a fi utilizată. Variabilele sunt declarate utilizând cuvântul cheie "my", fie atunci când variabila este atribuită, fie atunci când este utilizată pentru prima dată.

Modulul "Getopt::Long" implementează o funcție "getopt" numită GetOptions(). Acesta analizează linia de comandă de la @ARGV, recunoscând și eliminând opțiuni specificate și posibilele lor valori.

Această funcție respectă sintaxa POSIX pentru opțiunile liniilor de comandă, cu extensii GNU. De obicei acest lucru semnifică faptul că opțiunile au denumiri lungi în locul unor caractere unice și sunt introduse cu linie dublă "–". Suportul pentru implementarea opțiunilor liniilor de comandă, cum a fost cazul metodei tradiționale a caracterelor unice, este prevăzut însă nu este activat implicit.

Pentru a utiliza "Getopt::Long" într-un program Perl, trebuie inclusa în program următoarea linie de cod:

use Getopt::Long;

Această comandă va apela conținutul modulului "Getopt::Long" și va pregăti programul pentru utilizarea acestuia. Mare parte din codul modulului "Getopt::Long" nu este încărcat până când nu este apelată o funcție din cadrul acestuia.

"Getopt::Long" oferă două variante utile de opțiuni simple:

opțiuni de negare sunt specificate printr-un semn de exclamare (!) după numele opțiunii;

opțiuni de incrementare sunt specificate prin semnul plus după numele opțiunii.

Pentru opțiuni care iau valori, trebuie specificat dacă valoarea opțiunii este necesară sau nu și ce tip de valoare așteaptă opțiunea.

Sunt acceptate trei tipuri de valori: numere întregi, numere reale cu virgulă și șiruri de caractere.

Dacă valoarea opțiunii este necesară, "Getopt::Long" va lua argumentul liniei de comandă ce urmărește opțiunea și îl asignează variabilei opțiunii. Dacă, totuși, valoarea opțiunii este specifică ca fiind opțională, acest lucru va fi efectuat doar dacă acea valoare nu arată ea însăși ca o opțiune a liniei de comandă validă.

Aplicabilitatea în proiect

Dacă Interfața Grafică cu Utilizatorul a aplicației este asociată cu codul XAML, funcționalitatea (logica operațională) este asociată în spate cu codul C#. Deschiderea și afișarea fișierelor poate fi efectuată în mai multe modalități: selectând din meniu opțiunea "List" sau accesând butonul , ambele opțiuni având în spate același cod:

Fig. 3.1. Event-ul "OpenProtocol"

Pentru a deschide o fereastră de dialog in C#, este foarte ușor, trebuie scrisă doar prima linie de cod din funcția "OpenProtocol" și apoi cu caracteristica "ShowDialog", vă apare dialogul. Caracteristica "Filter" este utilizată pentru a vizualiza doar obiectele din folder care au pattern-ul “list.xml”.

Următorul pas constă în implementarea funcției "LoadProtocolData". În cadrul acesteia funcția de control "XMLDataProvider" creată în codul XAML, își încarcă datele în funcția de controlul "DataGrid" pentru a putea fi afișate. Atributul "X:Key" este utilizat pentru identificarea cărui "XMLDataProvider" îi corespunde ce "DataGrid". "XMLDataProvider" este activat în C# prin utilizarea metodei "FindResource".

După acest pas, va fi creat câte un document XML nou pentru fiecare tip de fișier, unul pentru fișierul cu diferențe și altul pentru fișierul ce include denumirile tuturor fișierelor. Chiar dacă sunt trei funcții de control "XMLDataProvider" și logic ar trebui să fie trei documente XML, sunt doar două pentru că în primul și al treilea document sunt încărcate informații din același fișier.

Pentru o bună funcționalitate, primul va fi verificat dacă fișierele XML sunt în folder-ul selectat printr-un bloc de instrucțiuni try-catch.

Fig. 3.2. Exemplu Try-Catch

Întrucât căutarea se face după un fișier, excepția care este stabilită este de tip "FileNotFoundException" și apoi este deschisă o fereastră cu un mesaj. Dacă fișierul există în folder, atunci acesta este încărcat cu metoda "Load" care ia atributul căii de acces către acel fișier.

Următorul pas este de verificare dacă elementele din fișierele XML conțin anumite atribute necesare; dacă fișierele sunt încărcate pentru prima dată, atributele lipsesc. În acest caz, acestea vor fi create de aplicația ”Instrument de evaluare al referințelor” și salvate cu valorile implicite.

Fig. 3.3. Crearea a noi atribute în documentul XML

În exemplul prezentat anterior se verifică dacă atributele limitei diferențiale absolute, limitei diferențiale relative și tabelul nivelului de detalii există. Valorile acestor atribute pot fi modificate din setările ferestrei iar dacă opțiunea de a compara diferențele este apăsată atunci valorile vor fi trimise către scriptul de Perl iar acesta va compara diferențele dintre aceste valori.

După ce toate verificările realizate cu ajutorul proprietății XPath ale XMLDataProvider -ului sunt efectuate, se va crea un nou document XML ce va conține toate modificările.

Fig. 3.4. Legătura dintre document si XMLDataProvider

Informațiile sunt afișate cu ajutorul controalelor DataGrid-ului cu o valoare a statusului „open”. Dacă utilizatorul dorește să vizualizeze diferențele sau fișierele cu valoarea statului „OK” sau “not OK”, atunci acesta are posibilitatea să comute valoarea statusului cu ajutorul controlului DropDownList care este poziționat deasupra controalelor DataGrid. Controlul DropDownList are anexat evenimentul ApplyChangeDisplayMode.

În fișierele status_change și status_file sunt salvate tipurile statusurilor selectate cu ajutorul atributului de tag ( valorile acestuia pot fi “all”,” open”,” OK”,” not OK”).

Fig.3.5. Evenimentul SelectionChanged din DropDownList

Fig.3.6. Evenimentul SelectionChanged din DropDownList

La sfârșitul funcției sunt apelate două metode, prima ApplyDifferenceSelection realizează o îmbinare a următorului control DataGrid cu fișierele în funcție de primul rând selectat din primul control DataGrid sau toate diferențele din acel control DataGrid și ApplyFileSelectionChange. A doua metodă apelează ApplyFilesChangedSelection, care realizează al treilea eveniment de control DataGrid și anume SelectionChanged. În primă instanță luăm atributul de tag al item-ului selectat din cadrul ComboBox-ului și verificăm dacă în cadrul celui de-al doilea control DataGrid există un rând selectat. Dacă da, atunci într-una din listele ale nodului XML vom salva toate nodurile care au copilul item-ului al fișierului selectat, altfel luăm toate nodurile conținute de fișier.

Fig. 3.7. Adăugarea unui nod într-o listă de noduri XML

Datorită faptului că în al treilea control de tip DataGrid sunt afișate diferențele, va fi suficientă o singură listă pentru toate nodurile.

Va fi creat un atribut temporar pentru fișierul diferențelor, iar dacă valoarea nodului este egala cu cea a atributului, acestuia i se va atribui „yes” , în caz contrar „no”.

Fig. 3.8.Verificarea egalității valorilor

Informația conținută în controlul DataGrid va fi actualizată în funcție de valorile noului atribut și valoarea selectată în cadrul item-ului DropDownList.

Fig. 3.9. Legăturile către documentele Xml

Proprietățile dependențelor sunt utilizate împreună cu îmbinările. Valoarea unei proprietăți de dependență poate fi legată de valoarea altei proprietăți, astfel încât schimbările efectuate asupra unei proprietăți în legătură se vor reflecta și pe legăturile acesteia.

Controlul DataGrid are avantajul de a sorta valorile conținute într-o coloană prin apăsarea header-ului acelei coloane. Sortarea este efectuată în funcție de tipul de date pe care coloana îl conține (în acest caz întâlnim sortări numerice și lexicografice). Pentru acest scop a fost adăugată o nouă clasa (DifferenceComparer) care implementează interfața standard IComparer.

Această interfață conține numai semnături CompareTo.

În exemplul următor sunt implementate semnăturile interfeței corespunzătoare tipului întreg (int) și compară atributele elementului XMLElement.

Fig.3.10 Funcția de comparare

Evenimentul de sortare pentru al treilea DataGrid conține următorul cod în spate:

Fig.3.11. Evenimentul SortFilesChanged

Acesta ia coloana pe care utilizatorul o alege pentru a fi sortată (în direcție ascendentă sau descendentă) iar aceste valori sunt parametrii de intrare pentru constructorul clasei DifferenceComparer și lista de itemi ce va fi sortată.

Datorită faptului că rezultatele Xml pot avea dimensiuni considerabil de mari, procesul de comparare a diferențelor poate avea o durată îndelungată de timp. Totuși aceste procese sunt independente deci comparările diferențelor pot fi plasate pe fire de execuție separate prin crearea a procese noi.

Parametrii necesari lansării în execuție a scriptului de Perl sunt trimiși cu ajutorul unui string de date. Acesta conține limita diferențială absolută, limita diferențiala relativă și tabelul nivelelor de detaliu, doar în cazul în care fișierul de diferențe există altfel, va apela valori implicite.

Fig. 3.12. Setarea parametrilor pentru script

Funcția ParallelCompareReferences utilizează următorii parametri:

calea către fișierul unde este localizat scriptul de Perl

calea către locația fișierului de protocol

variabila de tip string ce conține parametrii pentru script

Fig. 3.13 Funcția ParallelCompareReferences

Există două moduri prin care putem compara un fișier de tip protocol ca altul de tip referință:

serial – dacă în fișierul de protocol există valoarea atributului de status pentru un item

paralel – daca în status_model există două atribute pentru un item

Pentru ca fișierele ce conțin diferențe să fie luate în considerare, statusul și atributele de tip status_model trebuie să conțină valoarea “DIFF”. Pentru fiecare item care îndeplinește această condiție, se va colecta restul setului de atribute necesar pentru funcția de comparare implementată în scriptul Perl și îl va adaugă în variabila string necesară începerii noului proces.

Pentru fiecare proces ce va fi declanșat este necesar să asigurăm calea către scriptul de Perl cu ajutorul StartInfo.FileName, urmând ca proprietatea EnableRaisingEvents să primească valoarea “true”. Acest lucru simbolizează faptul că atunci când un proces își va finaliza execuția, acesta poate fi șters din lista proceselor, lucru care este realizat de care proprietatea “Exited” care va aplica evenimentul intitulat proc_Exited.

În cadrul evenimentului proc_Exited un proces este șters din lista proceselor pentru a ne asigura că funcția nu poate fi apelată de către alt proces al cărui final a invocat afirmația de blocare. Astfel prevenim blocarea execuției proceselor de către un proces nefinalizat.

Fig. 3.14. Evenimentul proc_Exited

Cu ajutorul StartInfo.Arguments parametrii sunt trimiși către scriptul Perl. Acesta în schimb returnează rezultatul cu ajutorul metodei GetOptions. Primul pas realizat este declararea variabilelor cu ajutorul cuvântului cheie “my” iar numele acestora trebuie plasat în interiorul parantezelor specifice apoi urmate de semnul “$”. Astfel variabilele își vor asigna implicit valorile parametrilor trimiși de către aplicație.

Fig 3.15 Exemplu de script Perl

Pentru a atinge performanță maximă, numărul proceselor executate trebuie să fie mai mic decât numărul procesoarelor deținute de către sistemul de calcul pe care rulează aplicația. Numărul de procesoare poate fi aflat cu ajutorul metodei Enviroment.ProcessorsCount. În structura repetitivă de tip “while” se verifică această condiționare iar dacă ea nu este îndeplinită atunci programul va aștepta încheierea unui proces înainte de a adăuga un proces nou în listă.

Atributul de “lock” are la rândul său aceeași semnificație precum ștergerea unui proces, abia după înlăturarea acestuia poate intra în execuție un alt proces.

La finalul funcției, rămâne un singur lucru de verificat și anume dacă lista proceselor este goală. În caz contrar programul va aștepta eliberarea listei.

Fig. 3.16. Bucla while – verifică dacă lista proceselor este goală

Evenimentul SetFilesChangedStatus este executat în momentul în care utilizatorul selectează opțiunea din meniul de context ce apare la apăsarea butonului drept al mouse-ului și permite schimbarea valorii statusului.

Fig.3.17 Preia identificatorul item-ului selectat în controlul DataGrid

În lista schimbărilor conținută în XmlNodeList, identificatorul nodului XmlNode al item-ului selectat din cea de-a treia grila de date este adăugat.

Fig.3.18. Verifică dacă lista este goală

Dacă în lista schimbărilor există itemi care conțin valoarea de adevăr a variabilei “dirty”, aceștia vor facilita salvarea schimbărilor în documentul de format Xml. În acest caz, pentru fiecare item din lista schimbărilor se va salva calea “xpath” a nodului afectat cât și valoarea statusului înainte ca acesta să sufere vreo modificare. Această acțiune este realizată pentru a furniza evenimentul butonului de “undo”, în cazul în care utilizatorul dorește să revină la valorile inițiale. Aceeași funcție va fi îndeplinită și de către statusul diferențelor conținute în documentul Xml.

Fig.3.19 Păstrează valorile statusului anterior pentru funcția de revenire (undo)

Pentru a salva schimbările efectuate asupra documentelor Xml va fi utilizat item-ul “save” din meniu sau cu ajutorul butonului de “save” încorporat în bara utilitară. Înainte de a stoca orice valoare nouă, funcția va verifica dacă valorile conținute de valoarea booleană “dirty”.

Fig 3.20 Verifică existența unor modificări efectuate în documentele Xml

În acest caz, documentele Xml vor fi salvate.

Fig. 3.21. Funcția “save”

Capitolul 4. Concluzia

Aplicația „Instrument de evaluare al referințelor” diminuează atât timpul cât și responsabilitatea necesară evaluării diferențelor ce pot apărea atunci când efectuăm un calcul de referință cu ajutorul aplicației BearinX. Datorită design-ului simplu și robust al acestei aplicații, utilizatorul poate localiza cu ușurință orice tip de diferență, locația acesteia și orice alte diferențe conținute de către acel fișier. Avantajul acesteia este că utilizatorul are posibilitatea de a seta statusul unei diferențe diferit (ex. “OK” într-un fișier și ”not OK” în altele), astfel dacă se selectează o anumită diferență, toate fișierele ce o conțin vor deveni vizibile, făcând utilizatorul capabil să ia o decizie rațională în momentul în care schimbă valoarea unui status. Schimbarea unui status într-un fișier va implica schimbarea tuturor diferențelor în conformitate cu acesta. Problema acestei situații este că utilizatorul nu dispune de timpul necesar pentru a verifica fiecare fișier și să verifice dacă acesta conține diferența. Soluția acestui fapt este aplicația „Instrument de evaluare al referințelor”: În momentul în care un utilizator va selecta un fișier, acesta va vedea toate schimbările anexate acestuia.

4.1. Îmbunătățiri viitoare:

Afișajul poate fi îmbunătățit astfel încât diferențele să aibă posibilitatea de a fi încărcate chiar în timp ce calculul referințelor se află încă în execuție. Acest lucru ar aduce schimbări display-ului și ar solicita aplicației să proceseze aceleași diferențe de mai multe ori.

Latura web-based a calculul referințelor poate fi exclusă integral, funcția acesteia fiind mutată în cadrul aplicației ”Instrument de evaluare al referințelor”.

Capitolul 5. Bibliografie

John C. Michell – ”Concepts in programming languages”, (2003) , Cambridge University Press;

Ian Griffiths, Matthew Adams, Jesse Liberty – ”Programming C# 4.0”, O’Reilly;

Adrian Turtschi, DotThatCom.com, Jason Werry, Greg Hack, Joseph Albahari, Saurabh Nandu, Wei Meng Lee – C#.Net Web Developer’s Guide, Syngress;

https://en.wikipedia.org/wiki/Windows_Presentation_Foundation;

https://en.wikipedia.org/wiki/C_Sharp_(programming_language);

Beginners Intro to Perl – Part 6 – Perl.com;

XmlDocument Class (System.Xml);

Polymorphism (C# Programming Guide).

Capitolul 5. Bibliografie

John C. Michell – ”Concepts in programming languages”, (2003) , Cambridge University Press;

Ian Griffiths, Matthew Adams, Jesse Liberty – ”Programming C# 4.0”, O’Reilly;

Adrian Turtschi, DotThatCom.com, Jason Werry, Greg Hack, Joseph Albahari, Saurabh Nandu, Wei Meng Lee – C#.Net Web Developer’s Guide, Syngress;

https://en.wikipedia.org/wiki/Windows_Presentation_Foundation;

https://en.wikipedia.org/wiki/C_Sharp_(programming_language);

Beginners Intro to Perl – Part 6 – Perl.com;

XmlDocument Class (System.Xml);

Polymorphism (C# Programming Guide).

Similar Posts