ATL [12] là bản cài đặt phù hợp với chuẩn OMG MOF/QVT RFP do nhóm
nghiên cứu AtlanMod thực hiện. ATL là ngôn ngữ chuyển đổi mô hình được đặc tả bằng cả metamodel và cú pháp cụ thể văn bản. Trong lĩnh vực (MDE), ATL cung cấp cho các nhà phát triển một con đường để tạo ra một tập các mô hình
đích từ một tập các mô hình nguồn. ATL là ngôn ngữ lai tạo giữa ngôn ngữ khai
báo và bắt buộc (declarative and imperative programming). Thông thường khi
viết các luật chuyển đổi thì ATL sử dụng kiểu khai báo: nó cho phép đơn giản
hóa việc thể hiện ánh xạ giữa mô hình nguồn và mô hình đích. Tuy nhiên ATL
cũng cung cấp cấu trúc bắt buộc (imperative constructs) để dễ dàng đặc tả ánh xạ khó thể hiện khi dùng kiểu khai báo.
Một chương trình chuyển đổi ATL bao gồm các luật xác định cách thức các phần tử mô hình nguồn được kết hợp và chuyển hướng đển các phần tử của mô hình đích. Bên cạnh chuyển đổi mô hình cơ bản, ATL định nghĩa một cơ sở truy
vấn mô hình cho phép xác định các yêu cầu đầu của vào mô hình.
Phát triển trên nền tảng Eclipse, môi trường phát triển tích hợp ATL cung
cấp một số công cụ phát triển tiêu chuẩn (đánh dấu cú pháp, sửa lỗi...) nhằm mục đích dễ dàng thiết kế các chuyển đổi ATL. Môi trường phát triển ATL còn cung cấp một số công cụ bổ xung dành riêng cho việc xử lý các mô hình và siêu mô hình. Những tính năng này bao gồm một hệ thống ký hiệu văn bản đơn giản dành riêng cho đặc tả siêu mô hình, nhưng cũng có một số cầu nối tiêu chuẩn giữa cú pháp văn bản thông thường và biểu diễn mô hình tương ứng.
Hình dưới đây cung cấp tổng quan quá trình chuyển đổi ATL
(Author2Person) sinh ra mô hình Person từ mô hình nguồn Author.
Hình 2.6- Tổng quan chuyển đổi mô hình trong ATL7 2.3.2 Cú pháp và ngữ nghĩa ATL
Ngôn ngữ ATL cho phép các nhà phát triển ATL thiết kế nhiều loại đơn vị
ATL khác nhau. Một đơn vị ATL (ATL unit) được định nghĩa trong tệp ATL
của nó. Các tệp ATL được phân biệt bởi phần mở rộng .atl.
ATL chủ yếu tập trung vào chuyển đổi mô hình. Những hoạt động chuyển
đổi đó được đóng gói thành một mô đun ATL. Ngoài mô đun ra, ngôn ngữ ATL
còn cho phép các nhà phát triển tạo ra các mô hình cho các chương trình có kiểu
dữ liệu cơ bản. Những đơn vị (unit) đó gọi là truy vấn ATL (ATL queries). Mục
đích của truy vấn là tính toán các giá trị nguyên thủy, ví dụ như là kiểu string
hay kiểu interger từ mô hình nguồn. Hơn nữa, ATL còn cho phép phát triển các
thư viện độc lập mà có thể import từ các đơn vị ATL khác, bao gồm cả bản thân các thư viện đó. Điều này cung cấp một con đường thuận tiện để tái sử dụng mã nguồn ATL được sử dụng trong nhiều đơn vị ATL. Hiện có 3 đơn vị ATL đều cùng sử dụng phần mở rộng .atl.
Phần dưới đây sẽ trình bày về 3 đơn vị ATL, sẽ giải thích mục đích sử dụng từng loại đơn vị và cung cấp tổng quan nội dung của 3 đơn vị.
ATL mô đun
a)
Một mô đun ATL tương ứng với một chuyển đổi một mô hình sang mô hình. Loại đơn vị ATL này cho phép các nhà phát triển ATL xác định cách thức để tạo ra một tập các mô hình mục tiêu từ một tập hợp các mô hình nguồn. Cả mô hình nguồn và mục tiêu của một mô đun ATL phải được “định kiểu” bởi metamodels tương ứng. Hơn nữa, một mô đun ATL chấp nhận một số cố định của các mô hình như là đầu vào, và trả về một số cố định của các mô hình mục tiêu. Như
vậy một mô đun ATL không thể tạo ra một số lượng không rõ các mô hình mục tiêu tương tự (ví dụ mô hình phù hợp với một cùng một metamodel).
Một mô đun ATL định nghĩa một chuyển đổi từ mô hình đến mô hình. Nó
bao gồm các thành phần: Header định nghĩa một số thuộc tính có liên quan đến các mô đun chuyển đổi, Import cho phép nhập khẩu một số thư viện ATL hiện có, Helper tập hợp các lớp trợ giúp có thể được xem như tương đương với các phương thức Java, Rules tập hợp các luật định nghĩa cách mô hình mục tiêu
được tạo ra từ những nguồn nguồn
Phần Helpers và Rules không thuộc về phần cụ thể nào trong một chuyển
đổi ATL. Chúng có thể được khai báo theo thứ tự bất kỳ tùy thuộc vào từng hoàn cảnh cụ thể. Bốn phần cơ bản sẽ được trình bày chi tiết trong phần dưới
đây:
Header: phần tiêu đề xác định tên của mô đun chuyển đổi và tên của các biến tương ứng với mô hình nguồn và mục tiêu. Nó cũng mã hóa các chế độ sử dụng mô đun. Cú pháp cho phần Header được định nghĩa như sau:
module module_name;
create output_models [from|refines] input_models;
Từ khóa module định nghĩa tên của mô đun. Cần lưu ý tên của tệp ATL chứa mã nguồn của mô đun phải có tên giống với tên của mô đun. Ví dụ, một mô đun chuyển đổi ModelA2ModelB phải được định nghĩa trong tệp ModelA2ModelB.atl.
Mô hình đích được khai báo bởi từ khóa create cùng với việc khai báo
mô hình nguồn bởi từ khóa from (trong chế độ thông thường) hay refines
(trong trường hợp chuyển đổi làm mịn mô hình). Khai báo mô hình, dù là
một đầu vào hay đầu ra, phải phù hợp với cấu trúc model_name : metamodel_name. Có thể khai báo nhiều hơn một mô hình nguồn hoặc
mô hình đích bằng cách tách các khai báo mô hình bằng dấu phẩy. Lưu ý
rằng tên của các mô hình khai báo sẽ được sử dụng để nhận dạng. Cho nên mỗi tên mô hình được khai báo phải là duy nhất trong tập các mô hình được khai báo (cả đầu vào và đầu ra).
Import: phần tùy chọn Import cho phép khai báo các thư viện ATL được sử dụng trong chương trình. Khai báo của một thư viện ATL được thực hiện như sau:
uses extensionless_library_file_name;
Ví dụ, để sử dụng các thư viện chuỗi, người ta sẽ viết:
uses strings;
Lưu ý rằng có thể khai báo một số thư viện khác nhau bằng cách sử dụng nhiều lệnh uses.
Helpers trong ATL có thể được xem như tương đương với phương thức
trong Java. Helper giúp định nghĩa các đoạn mã ATL có thể được gọi từ
các điểm khác nhau trong chuyển đổi ATL.
Một ATL Helper được xác định bởi các yếu tố sau:
o Tên (tương ứng với tên của phương thức)
o Loại ngữ cảnh định nghĩa ngữ cảnh trong đó thuộc tính này
nghĩa trong ngữ cảnh của lớp tương ứng trong lập trình hướng
đối tượng).
o Kiểu giá trị trả về. Lưu ý rằng, trong ATL, mỗi helper phải có một giá trị trả về;
o Chỉ lệnh ATL đại diện cho mã của ATL Helper.
o Một tập hợp tùy chọn các thông số, trong đó mỗi tham số được xác định bởi một cặp (tên tham số: kiểu tham số).
Ví dụ, định nghĩa một helper trả về giá trị lớn nhất của 2 số nguyên.
helper context Integer def: max(x : Integer): Integer = ...;
Rule trong ATL có 2 loại tương ứng với hai chế độ lập trình khác nhau
được cung cấp bởi ATL (ví dụ như kiểu khai báo hay bắt buộc): mached rules (dạng khai báo) và called rules (dạng bắt buộc).
o Matched rules: các luật này tạo thành cốt lõi của một chuyển đổi khai báo ATL khi nó có thể xác định loại của phần tử nguồn mà các phần tử đích được sinh ra và cách khởi tạo các phần tử đích. Một matched ruleđược xác định bởi tên của nó. Nó kết hợp các kiểu của phần tử mô hình nguồn và tạo ra một hoặc nhiều loại của phần tử mô hình đích. Luật xác định cách tạo các phần tử
mô hình đích cần phải phù hợp với phần tử mô hình nguồn.
Khai báo nguồn của matched rules được định nghĩa sau từ khóa
from. Nó cho phép xác định một biến phần tử mô hình tương
ứng với kiểu của các phần tử đích mà luật phải phù hợp. Kiểu này tương ứng với một thực thể của metamodel nguồn của phép chuyển đổi. Điều này có nghĩa rằng luật sẽ tạo ra các phần tử đích cho mỗi phần tử mô hình nguồn mà phù hợp với kiểu đó. Khai báo đầu ra của luật phù hợp được đặt sau tử khóa to. Mục
đích là xác đích các phần tử sẽ được tạo ra khi phần tử nguồn của luật được làm phù hợp và cách những phần tử tạo ra đó
được khởi tạo. Phần chỉ lệnh bắt buộc tùy chọn, được đưa ra sau từ khóa do, qua đó có thể xác định mã nguồn bắt buộc sẽ thực thi sau sự khởi tạo của các phần tử đích được tạo ra bởi luật.
Ví dụ một matched rules ATL: rule Author { from a : MMAuthor!Author to p : MMPerson!Person ( name <- a.name, surname <- a.surname ) }
o Called rules: cung cấp cho các nhà phát triển ATL một công cụ
ngôn ngữ bắt buộc thuận tiện. Called rules cũng có thể được coi như là một helpers: chúng phải được gọi chính xác khi thực thi và có thể chấp nhận các biến. Tuy nhiên, ngược lại với helpers,
called rules có thể tạo ra các phần tử mô hình đích như là
matched rules. Một called rules phải được gọi từ vùng mã nguồn bắt buộc hoặc từ một matched rule khác hay called rule
khác. Giống như matched rule, một called rule được đặt sau từ
khóa rule. Called rules có thể bao gồm phần biến cục bộ tùy
chọn. Tuy nhiên vì nó không phải làm phù hợp các phần tử mô
hình nguồn nên called rule không chứa các mẫu nguồn. Hơn nữa mẫu mô hình mà có khả năng tạo các phần tử mô hình đích cũng là tùy chọn. Lưu ý rằng vì called rule không làm phù hợp bất kỳ các phần tử mô hình nguồn nào nên sự khởi tạo của các phần tử mô hình đích mà được tạo bởi mẫu đích phải dựa trên sự
kết hợp của các biến cục bộ, tham số và thuộc tính của mô đun. Mẫu đích của called rule được định nghĩa giống mẫu đích của
matched rule. Nó cũng được định nghĩa sau từ khóa to. Một
called rule có thể có phần bắt buộc tương tự như phần được định nghĩa trong matched rules. Lưu ý rằng phần mã nguồn bắt buộc là không bắt buộc, có thể xác định một called rule mà chỉ chứa phần mẫu đích hay phần mã nguồn bắt buộc. Dưới đây là một ví dụ về cấu trúc called rule:
rule NewPerson (na: String, s_na: String) { to p : MMPerson!Person ( name <- na ) do { p.surname <- s_na } }
Chế độ thực thi mô đun
b)
ATL định nghĩa hai chế độ thực thi khác nhau cho các mô đun ATL. Với
chế độ thực thi mặc định, các nhà phát triển ATL phải xác địch rõ ràng cách các phần tử mô hình đích phải được tạo ra từ các phần tử mô hình nguồn.
Trong phạm vi này, thiết kế của một chuyển đổi nhằm mục đích sao chép mô hình nguồn chỉ với một vài thay đổi nhỏđã được chứng minh là rất hạn chế. Thiết kế chuyển đổi này trong chế độ thực thi mặc định đòi hỏi các nhà phát triển xác định các quy luật sẽ tạo ra các phần tử mô hình sửa đổi, mà còn tất cả
các luật sẽ chỉ sao chép mà không sửa đổi. Chế độ thực thi tinh chỉnh (refining)
đã được thiết kế cho loại tình huống này, nó cho phép các nhà phát triển ATL
chỉ xác định những sửa đổi cần phải được thực hiện giữa nguồn chuyển đổi và mô hình mục tiêu. Chế độ thực thi được mô tả trong các phần dưới đây:
Chế độ thực thi Normal: là chế độ mặc định của mô đun ATL. Nó được kết hợp với từ khoá from trong tiêu đề mô đun. Trong chế độ thực thi mặc định, các nhà phát triển ATL phải xác định (dù là luật matched rules
hay called rules) các cách để tạo ra từng phần tử mô hình đích mong đợi. Chế độ này phù hợp với hầu hết các chuyển đổi ATL nơi mô hình đích
khác với mô hình nguồn.
Chế độ thực thi Refining: Chế độ này đưa ra để giảm bớt quá trình chuyển đổi tinh chỉnh giữa mô hình nguồn và đích tương tự nhau. Với
chế độ tinh chỉnh, các nhà phát triển ATL có thể tập trung vào các mã
ATL dành riêng cho việc tạo ra các phần tử đích đã thay đổi. Các phần tử
mô hình khác (ví dụ những thành phần không thay đổi giữa nguồn và mô
hình mục tiêu) được mặc nhiên sao chép từ nguồn đến các mô hình mục
Truy vấn ATL
c)
Ngoài mô đun, ATL còn cho phép định nghĩa các truy vấn trên mô hình. Một truy vấn sử dụng một số lượng mô hình nguồn và trả về một giá trịđơn của bất kỳ kiểu dữ liệu nguyên thủy nào. Một đơn vị truy vấn bao gồm một phần tử
truy vấn đơn cùng với các helpers và thuộc tính được định nghĩa trong ngữ cảnh
của mô đun ATL hay bất kỳ các phần tử mô hình nào định nghĩa trong mô hình
nguồn truy vấn. Lưu ý rằng đơn vị truy vấn ATL phải bắt đầu với khai báo các phần tử truy vấn.
Truy vấn ATL được khai báo như sau:
query query_name = exp;
Thư viện ATL
d)
Kiểu đơn vị cuối cùng của ATL là thư viện ATL. Phát triển một thư viện ATL cho phép định nghĩa tập các lớp trợ giúp ATL mà có thể gọi từ các đơn vị
khác nhau của ATL.
Không giống như ATL mô đun, trong thư viện ATL không có các phần tử
mặc định. Cho nên trong thư viện không thể mô tả các lớp trợ giúp trong ngữ
cảnh mặc định như của mô đun. Có nghĩa là tất cả lớp trợ giúp định nghĩa trong thư viện ATL cần phải liên kết với một ngữ cảnh.
So sánh với truy vấn ATL, một thư viện ATL không thể thực thi độc lập.
Điều này có nghĩa là thư viện không liên kết với bất kỳ bước khởi tạo nào tại thời điểm thực thi. Vì thiếu bước khởi tạo nên lớp trợ giúp thuộc tính không thể định nghĩa trong thư viện ATL.
2.3.3 Kiến trúc ATL
Kiến trúc ATL bao gồm:
Phần lõi (Core): mô tả khái niệm ATL theo một cách trừu tượng
Bộ phân tích (Parser) và bộ biên dịch (Compiler)
Máy ảo (Virtual Machines) cho phép thực thi chuyển đổi
Môi trường phát triển: bao gồm trình soạn thảo, trình gỡ lỗi, dựa trên các thành phần đề cập ở trên.
Hình 2.7- Kiến trúc ATL [12]
Máy ảo ATL VM nằm giữa trình biên dịch ATL và các frameworks được sử
dụng (EMF, MDR) cho phép mô đun hóa. Do đó các thay đổi trên ngôn ngữ
ATL chỉ liên quan đến trình biên dịch ATL.
Phần lõi (Core)
a)
Hình dưới đây mô tả phần lõi ATL và cách tương tác với các công cụ như
Hình 2.8- Phần lõi ATL [12]
IModel là một biểu diễn phù hợp của mô hình phù hợp cho chuyển đổi ATL. Nó cung cấp các phương thức để tìm kiếm các phần tử, tạo mới, vv...
Giao diện IReferenceModel mở rộng IModel và là một phiên bản cụ thể của
IModel mà tượng trưng cho siêu mô hình. Nó định nghĩa các hoạt động dành
riêng cho siêu mô hình mà hữu ích cho chuyển đổi ATL.
ModelFactory dành riêng cho tạo mô hình và mô hình tham chiếu.
Giao diện IInjector, IExtractor cung cấp một cách để nạp và lưu mô hình
được tạo tử trước bởi modelFactory
Giao diện ILauncher dành riêng cho cài đặt bởi máy ảo ATL: nó định nghĩa
các phương thức để tham số hóa và khởi động một chuyển đổi.
Dịch vụ (services): Để đơn giản hóa việc sử dụng phần lõi ATL và giảm
trùng lặp mã nguồn, 2 dịch vụđược cung cấp: CoreService và LauncherService
Các lớp tiện ích đều cung cấp một cách thức để nhìn vào các phần mở rộng hay bộ nhớ cục bộ cho cài đặt Core.
LauncherService cho phép gọi một chuyển đổi từ tập các biến giống như bản
đồ đường dẫn và bản đồ của tên mô hình: nó có liên quan chặt chẽ tới cấu hình và các tác vụ như cho phép gọi chuyển đổi trên các máy ảo.
Máy ảo ATL
b)
Máy ảo ATL VM là bộ thông dịch byte code mà quản lý kiểu phân cấp của
OCL và ATL. Hình dưới đây mô tả hoạt động của ATL VM
Hình 2.9- Lược đồ hoạt động máy ảo ATL [12]
Trong quá trình khởi tạo ATL VM, mọi hoạt động đều được đăng ký vào