Trong phần này, luận án tập trung vào kỹ thuật sinh mã tự động trong phát triển ứng dụng web hướng mô hình theo phương pháp UWE. Nội dung chính gồm:
(1) Xây dựng 03 quy tắc sinh mã từ mô hình PSM: Quy tắc CM2M sinh mã thành phần Model từ mô hình nội dung; Quy tắc PRES2V sinh mã thành phần View từ mô hình trình bày và quy tắc NPROM2C sinh mã thành phần Controller từ mô hình điều hướng và xử lý. Tương ứng với 03 quy tắc này, tác giả đã xây dựng 03 giải thuật sinh mã: CM2M, NPROM2C, PRES2V.
(2) Từ các quy tắc, giải thuật đã phát triển, tác giả đã xây dựng công cụ CODEGER-UWE để hỗ trợ sinh mã nguồn cho phát triển ứng dụng web.
Trong mục 2.3 của luận án đã trình bày bộ quy tắc chuyển đổi từ mô hình yêu cầu sang mô hình xử lý và mô hình trình bày, nhằm cải thiện quá trình chuyển đổi tự động cho các ứng dụng web sử dụng UWE. Trong nghiên cứu này, tác giả đề xuất xây dựng thêm các giải thuật để chuyển đổi từ mô hình PSM sang code (hình 3.2)
Hình 3.2. Sinh code trong UWE
Trong kỹ thuật Template và Metamodel mã được tạo bằng cách áp dụng khuôn mẫu cho đặc tả mô hình văn bản (thường là XML/XMI) [17]. Một cách trực quan cho
yêu cầu này là cách tiếp cận dựa trên template, nơi mà văn bản được sinh ra từ mô hình, được quy định như là một tập các template dạng văn bản mà được tham số hóa với các phần tử mô hình. Một Template xác định một template văn bản cùng với các điểm mốc (placeholders) cho dữ liệu được trích xuất ra từ mô hình. Những điểm mốc đó về bản chất là các biểu thức quy định các thành phần metamodel cùng với các truy vấn, là cơ chế chính cho việc lựa chọn và trích xuất giá trị từ mô hình. Giá trị đó được chuyển đổi qua văn bản bằng cách sử dụng ngôn ngữ biểu thức dựa trên các thư viện xử lý chuỗi. Template có thể được sử dụng để giải quyết các yêu cầu chuyển đổi phức tạp và chủ yếu được sử dụng để tạo mã nguồn cho các ứng dụng trong nhiều lĩnh vực khác nhau [97].
Vì vậy, trong nghiên cứu này, tác giả sử dụng phương pháp khuôn mẫu và metamodel với nền tảng công nghệ J2EE, mô hình Web MVC cho phương pháp UWE, kết hợp với sự tương đồng về mặt định nghĩa của bốn mô hình trong UWE là mô hình nội dung, điều hướng, xử lý, trình bày, tương ứng với ba thành phần trong mô hình MVC. Tác giả đề xuất quy trình chuyển đổi MDA cho phương pháp UWE như Hình 3.3.
Hình 3.3. Chuyển đổi sang mã nguồn theo mô hình MVC
Tác giả đã xây dựng 03 quy tắc sinh code: Quy tắc CM2M sinh mã thành phần Model từ mô hình nội dung; Quy tắc PRES2V sinh mã thành phần View từ mô hình trình bày và Quy tắc NPROM2C sinh mã thành phần Controller từ mô hình điều hướng và xử lý (Chi tiết được thể hiện trong bảng 3.1). Tác giả cũng đã xây dựng thành công cụ CODEGER –UWE, nhằm hỗ trợ sinh mã tự động cho phát triển ứng dụng web.
Bảng 3.1. Danh sách các quy tắc sinh code xây dựng
TT Tên quy tắc Ý nghĩa
1 Quy tắc CM2M Thành phần trong lớp của mô hình nội
dung được chuyển đổi sang JavaModel 1.1
UWEClass2JavaClass Tạo lớp JavaBean tương ứng với một lớp trong mô hình nội dung.
1.2
UWEProperty2JavaClassMember
Mỗi một thuộc tính của lớp được chuyển đổi tương ứng thành một trường (field) trong JavaBean.
1.3
UWEOperation2JavaMethod
Mỗi một thủ tục (operation) được chuyển đổi tương ứng thành một phương thức (method).
1.4 JavaModel2SourceCode Sinh mã nguồn Java từ JavaModel
2
Quy tắc PRES2V Các lớp của mô hình trình bày được
chuyển đổi sang JSPModel. 2.1
PreElement2JSP
Lớp có khuôn mẫu là văn bản (text), nút bấm (button),…, được chuyển đổi thành các thành phần tương ứng trong JSP.
2.2
PreClass2JSP
Lớp có khuôn mẫu là trang (presentationPage), biểu mẫu
(inputform),… chuyển đổi thành các thành phần tương ứng trong JSP. 2.3 JSPModel2SourceCode Sinh mã nguồn Java từ JSPModel
3 Quy tắc NPROM2C
Quy tắc sinh mã thành phần Controller từ mô hình điều hướng và sinh mã từ mô hình xử lý.
3.1
Navi2JavaClass Tạo lớp Controller từ lớp điều hướng được đánh dấu "isHome"
3.2
NaviNode2JavaClass
Các lớp xử lý, truy vấn được chuyển đổi thành một phương thức trong lớp Controller.
3.3
UWEClass2JavaClass
Tạo lớp Java tương ứng với một lớp trong mô hình xử lý, giữ nguyên sự kế thừa giữa các lớp.
a) Quy tắc CM2M sinh mã thành phần Model từ mô hình nội dung
Mô hình nội dung sử dụng thành phần mô hình UML chuẩn cho mô hình cấu trúc như các lớp, các liên kết và các gói để mô hình hóa nội dung ứng dụng Web.
Các lớp, các thành phần trong lớp của mô hình nội dung được chuyển đổi sang JavaModel thông qua ba quy tắc chuyển đổi cấp mô hình: UWEClass2JavaClass, UWEProperty2JavaClassMember, UWEOperation2JavaMethod, và quy tắc chuyển đổi mô hình sang mã nguồn JavaModel2SourceCode, thể hiện như hình 3.4.
Hình 3.4. Các quy tắc cấu thành giải thuật CM2M
- Quy tắc UWEClass2JavaClass
Mỗi một lớp trong mô hình nội dung được chuyển đổi thành một lớp JavaBean. Quy tắc được mô tả như sau:
Đầu vào: Lớp trong mô hình nội dung. Đầu ra: JavaClass với các thuộc tính:
-Name: Tên của lớp đầu vào.
-SuperClasses: Tên của lớp đầu vào được kế thừa. -Các thuộc tính khác được gán các giá trị phù hợp.
Trong quy tắc này, đầu vào là các lớp trong mô hình nội dung (JSPNode và LSPElement), những lớp này được chuyển đổi thành JavaClasses.
- Quy tắc UWEProperty2JavaClassMember
Mỗi một thuộc tính (attribute) trong mô hình nội dung được chuyển đổi tương ứng thành một trường (field) trong JavaBean có phạm vi truy cập là "private", đi cùng là hai phương thức truy cập (getter), gán giá trị (setter) tương ứng có phạm vi truy cập là "public". Quy tắc được mô tả như sau:
Đầu vào: Thuộc tính của lớp (thuộc tính có tên là "name", có kiểu dữ liệu là "String").
Đầu ra: JavaField, JavaMethod (hàm getter), JavaMethod (hàm setter). Trong đó:
-JavaField có các thuộc tính:
+ Name: "_" + tên của thuộc tính.
+ Type: kiểu dữ liệu của thuộc tính.
+ Initialize: Khởi tạo giá trị dựa trên kiểu dữ liệu thuộc tính.
+ Các thuộc tính khác được gán các giá trị phù hợp. -JavaMethod (getter) có các thuộc tính:
+ Name: "get" + tên của thuộc tính
+ Type: Kiểu dữ liệu của thuộc tính
+ Body: Trả về JavaField
+ Các thuộc tính khác được gán các giá trị phù hợp. -JavaMethod (setter) có các thuộc tính:
+ Name: "set" + tên thuộc tính
+ Parameter: Tạo tham số truyền vào theo tên và kiểu dữ liệu thuộc tính
+ Body: Gán giá trị cho JavaField
+ Các thuộc tính khác được gán các giá trị phù hợp. - Quy tắc UWEOperation2JavaMethod
Mỗi thủ tục (operation) trong mô hình nội dung được chuyển đổi tương ứng thành một phương thức (method), có cùng kiểu dữ liệu trả về và tham số đầu vào. Nội dung phương thức là mặc định. Quy tắc được mô tả như sau:
Đầu vào: Phương thức của lớp (phương thức "toCode" của lớp JSPNode có kiểu dữ
liệu trả về là "String", không có tham số)
Đầu ra: JavaMethod với các thuộc tính:
-Name: Tên của phương thức đầu vào. -Type: Kiểu dữ liệu trả về của phương thức. -Parameter: Tham số của phương thức.
-Body: Trả về giá trị mặc định, phụ thuộc vào kiểu dữ liệu trả về của phương thức. -Các thuộc tính khác được gán các giá trị phù hợp.
b) Quy tắc PRES2V sinh mã thành phần View từ mô hình trình bày
Mô hình trình bày mô tả một cái nhìn trừu tượng về giao diện người dùng của ứng dụng. Mô hình trình bày được xây dựng trên các định nghĩa khuôn mẫu (stereotype) cho các loại thành phần khác nhau, ví dụ khung nhập văn bản (text), các nút bấm (button), …
Các lớp của mô hình trình bày được chuyển đổi sang JSPModel thông qua hai quy tắc chuyển đổi cấp mô hình PreElement2JSP, PreClass2JSP và quy tắc chuyển đổi mô hình sang mã nguồn JSPModel2SourceCode, thể hiện như hình 3.5.
- Quy tắc PreElement2JSP
Quy tắc này chuyển đổi các thành phần UIElement trong mô hình trình bày sang JSP element. Lớp có khuôn mẫu là văn bản (text), nút bấm (button), khung nhập văn bản (text input), hình ảnh (image), mỏ neo (anchor),…, được gọi chung là UIElement, được chuyển đổi thành các thành phần tương ứng trong JSP. Quy tắc được mô tả cụ thể như sau:
Đầu vào: Lớp trong mô hình trình bày (lớp có tên là "Introduction" có khuôn mẫu
là văn bản).
Đầu ra: JSPElement. Tùy thuộc vào khuôn mẫu của lớp đầu vào, đầu ra
JSPElement sẽ có các lớp con JSPElement, JSPAttribute, JSPTextNode, JSPNode với số lượng, thuộc tính khác nhau. Trong đó: JSPElement có thuộc tính name có giá trị là "c:out", và JSPAttribute là con của JSPElement, có thuộc tính: name: "value"; value: Được xây dựng trên cơ sở tên của lớp đầu vào.
- Quy tắc PreClass2JSP
Quy tắc chuyển đổi các thành phần lớp sang JSP element. Lớp có khuôn mẫu là trang (presentationPage), biểu mẫu (inputform), nhóm (presentationGroup), khung thay thế (presentationAlternative). Ngoài việc được chuyển đổi thành các thành phần tương ứng trong JSP, còn cần xác định các lớp con được chứa bên trong và tiếp tục quá trình chuyển đổi. Quy tắc được mô tả cụ thể như sau:
Đầu vào: Lớp, trong mô hình trình bày (lớp có tên là "SearchForm" có khuôn mẫu
là biểu mẫu).
Đầu ra: JSPElement. Tùy thuộc vào khuôn mẫu của lớp đầu vào, đầu ra
JSPElement sẽ có các lớp con JSPElement, JSPAttribute, JSPTextNode, JSPNode với số lượng, thuộc tính khác nhau. Ngoài ra, các lớp con có trong lớp đầu vào tiếp tục được chuyển đổi, dựa trên khuôn mẫu của nó bằng cách gọi lại chính PreClass2JSP (thực hiện đệ quy) hay quy tắc PreElement2JSP.
JSPElement có thuộc tính name có giá trị là "form", có hai lớp con JSPAttribute với các thuộc tính có giá trị được xây dựng trên cơ sở tên lớp đầu vào, có lớp con JSPElement có thuộc tính name là "table" chứa lớp chuyển đổi của các lớp là con của lớp đầu vào. Lớp "SearchCriterion" có khuôn mẫu là khung nhập văn bản và lớp "Search" có khuôn mẫu là nút bấm.
c) Quy tắc NPROM2C sinh mã thành phần Controller từ mô hình điều hướng và xử lý Trong NPROM2C gồm 2 quy tắc chính: NM2C sinh mã thành phần Controller từ mô hình điều hướng, PROM2C sinh mã từ mô hình xử lý.
❖ Quy tắc NM2C
Mô hình điều hướng, mô tả luồng chuyển hướng tương ứng với hành động người sử dụng trong ứng dụng Web, được thể hiện bằng biểu đồ lớp và bổ sung các khuôn
mẫu UWE đại diện cho các nút, các liên kết,… Các thành phần lớp có trong mô hình, gồm: Lớp điều hướng, lớp xử lý, lớp truy vấn, lớp chỉ mục, thực đơn và các liên kết giữa các lớp có trong mô hình.
Mô hình điều hướng được thể hiện dưới dạng đồ thị, với nút gốc là lớp điều hướng (navigationClass) có đánh dấu "isHome".
Các lớp điều hướng được đánh dấu "isHome", lớp truy vấn, lớp xử lý được chuyển đổi sang JavaModel thông qua hai quy tắc chuyển đổi cấp mô hình: Navi2JavaClass, NaviNode2JavaMethod, và quy tắc chuyển đổi mô hình sang mã nguồn JavaModel2SourceCode, thể hiện như trong hình 3.6.
Hình 3.6. Các quy tắc cấu thành giải thuật NM2C
- Quy tắc Navi2JavaClass
Tạo lớp Controller từ lớp điều hướng được đánh dấu "isHome", Quy tắc được mô tả như sau:
Đầu vào: Lớp điều hướng đánh dấu "isHome" trong mô hình điều hướng (lớp có
tên là "AddressBook).
Đầu ra: JavaClass có:
-Thành phần thuộc tính
+ Name: Được tạo dựa trên tên của lớp đầu vào.
+ Annotation: được gán giá trị "@Controller", là annotation của SpringMVC.
+ Các thuộc tính khác được gán các giá trị phù hợp. -Thành viên lớp JavaMethod
+ Name: "Home"
+ Các thuộc tính annotation, type, body được gán giá trị theo cấu hình của SpringMVC.
+ Các thuộc tính khác được gán các giá trị phù hợp. - Quy tắc NaviNode2JavaClass
Các lớp xử lý, truy vấn được chuyển đổi thành một phương thức trong lớp Controller, đi kèm với mỗi lớp là liên kết điều hướng tương ứng. Ta xây dựng lớp NaviNode để tiện việc lưu trữ. Quy tắc được mô tả như sau:
Đầu vào: NaviNode, được tạo để lưu trữ thông tin từ lớp xử lý, truy vấn trong mô
hình điều hướng (lớp xử lý có tên là "CreateCreation".).
Đầu ra: JavaMethod có các thuộc tính:
-Annotation: Được tạo từ thành phần linkNode trong NaviNode. -Các thuộc tính khác được gán các giá trị phù hợp.
❖ Quy tắc PROM2C
Mô hình xử lý mô tả chi tiết quá trình xử lý được thực hiện như thế nào, thể hiện bằng biểu đồ lớp. Mô hình có cấu trúc, cách thể hiện như mô hình nội dung.
Các lớp, các thành phần trong lớp của mô hình xử lý được chuyển đổi sang JavaModel thông qua ba quy tắc chuyển đổi cấp mô hình: UWEClass2JavaClass, UWEProperty2JavaClassMember, UWEOperation2JavaMethod và quy tắc chuyển đổi mô hình sang mã nguồn JavaModel2SourceCode, thể hiện trong hình 3.7.
Hình 3.7. Các quy tắc cấu thành giải thuật PROM2C
Trong đó, quy tắc UWEClass2JavaClass, UWEProperty2JavaClassMember và quy tắc UWEOperation2JavaMethod đã được trình bày tại phần 3.1. Quy tắc UWEClass2JavaClass được mô tả như sau:
Đầu vào: Lớp, trong mô hình nội dung. Đầu ra: JavaClass với các thuộc tính:
-Name: Tên của lớp đầu vào.
-SuperClasses: Tên của lớp đầu vào được kế thừa. -Các thuộc tính khác được gán các giá trị phù hợp.
Trong quy tắc này, mỗi lớp trong mô hình xử lý được chuyển đổi thành một lớp Java. Tạo ra lớp Java tương ứng với một lớp trong mô hình xử lý và giữ nguyên sự kế thừa giữa các lớp.