Từ tiến trình chuyển đổi (tham khảo Hình 3.31) cho thấy chuyển đổi mô hình
sang văn bản Model-to-Text (JET) lấy đầu vào từ mô hình phụ thuộc nền (UWE4JSF-
PSM) để tạo mã nguồn cho ứng dụng JSF. Nhưđã đề cập thì công nghệ Java Emitter
Templates (JET) được sử dụng như bộ xử lý (engine) trong việc chuyển đổi này.
Chuyển đổi M2T được phân chia thành nhiều khuôn mẫu JET (templates)
thực hiện việc chuyển đổi các khía cạnh nội dung, xử lý, điều hướng và diễn tả của
mô hình UWE-PSM sang dạng mã nguồn, trong đó có một khuôn mẫu trung tâm được
đặt tên main.jet (tham khảo file template này trong plug-in *.m2t_1.1.11.jar,
trình bày Phụ Lục A) sử dụng nhưđiểm khởi đầu và được gọi cùng với file cấu hình uwe4jsf-config.xml như là đầu vào. Các thiết lập đã được mô tả trong file cấu hình
này, trong đó mô hình UWE-PSM được tải vào một biến và được sử dụng như một
biến toàn cục cho việc xử lý. Từđó, các khuôn mẫu tương ứng được gọi cho mỗi phần của ứng dụng. Có thể thấy điều này trong đoạn mã được trích từ file main.jet như
sau:
main.jet
<%@taglib prefix="ws" id="org.eclipse.jet.workspaceTags" %> <%@taglib prefix="UWE4JSF"
id="de.lmu.ifi.pst.uwe.UWE4JSF.jetextensions.standardHelpers" %> <%@jet imports="org.eclipse.emf.ecore.*"%>
<c:load url="{$org.eclipse.jet.resource.parent.name}/{/UWE4JSF/models/jsfPSM}" urlContext="workspace" loader="org.eclipse.jet.emf" var="psmInput"/>
<c:setVariable var="application" select="$psmInput/contents"/>
<c:include template="templates/javaPackage.jet"/> etc.
</c:iterate> ...
<ws:folder path="{$org.eclipse.jet.resource.parent.name}/WebContent"> <c:iterate select="$application/view" var="view">
<ws:file path="{$view/@name}.jsp" template="templates/jsfView.jet"/> </c:iterate>
<ws:file path="index.jsp" template="templates/index_jsp.jet"/> </ws:folder>
<ws:folder path="{$org.eclipse.jet.resource.parent.name}/WebContent/WEB-INF"> <ws:file path="faces-config.xml" template="templates/faces-config_xml.jet"/> </ws:folder>
<c:iterate select="$application/dataFlowModel" var="dfm"> <c:include template="templates/dataFlowModel.jet"/> </c:iterate>
...
Để ý các dòng in đậm, trong đó mô hình UWE-PSM được tải và nội dung của nó
được lưu vào một biến “var=psmInput”. URL của mô hình đầu vào khai báo bởi một
truy vấn Xpath dạng chuỗi (string) lấy thông tin mô hình từ file cấu hình uwe4jsf-
config.xml. Tiếp đến một vòng lặp qua các tập thành phần được khai báo bởi thẻ
(tag) <c:iterate>, tương ứng với mỗi khuôn mẫu JET được gọi. Đầu ra thì có thể
theo nhiều cách, đơn cử như với main.jet thẻ <ws:file> được sử dụng để xuất nội dung ra một file có đường dẫn cụ thể.
uwe4jsf-config.xml ... <models> <!-- --> <umlSourceModel>model/emfuml/AddressBook.uml</umlSourceModel> <uwePIM>model/AddressBook.uwe.xmi</uwePIM> <jsfPSM>model/AddressBook.uwejsf.xmi</jsfPSM> <concretePresentationDefaults> model/mappingDefaults/presentationMappingDefaults.uwe.xmi </concretePresentationDefaults> </models>
... <contentPackageConfig> <modelPackage>content</modelPackage> <applicationPackage> de.lmu.ifi.pst.uwe.examples.addressbook.content </applicationPackage>
<generate>true</generate>
</contentPackageConfig>
...
Việc gọi một khuôn mẫu cũng có thểđược thực hiện theo kiểu đệ quy, dẫn thẳng
tới việc sinh các gói Java theo hình thức rất ngắn gọn như mô tả ở khuôn mẫu
javaPacket.jet . Ngoài lời gọi đệ quy cho việc xử lý các gói con, thì còn có khía cạnh thú vị khác, đó là một gói chỉ được tạo khi việc tạo được kích hoạt bởi
đầu vào tương ứng “contentPackageConfig” trong file cấu hình uwe4jsf-
config.xml. Tức là một biến được gán bởi truy vấn Xpath mà lấy thông tin từ file cấu hình, sử dụng điều kiện <c:if> để kiểm tra xem việc sinh mã có hợp lệ hay không. Xem biến “test” ởđoạn in đậm dưới đây.
javaPackage.jet
<%@taglib prefix="java" id="org.eclipse.jet.javaTags"%> <%@taglib prefix="UWE4JSF"
id="de.lmu.ifi.pst.uwe.UWE4JSF.jetextensions.standardHelpers" %> <%@jet imports="org.eclipse.emf.ecore.*"%>
<c:set select="$pkg" name="qualifiedName"> <UWE4JSF:getQualifiedName select="$pkg"/> </c:set>
<c:set select="$pkg" name="generate"> <c:choose>
<c:when
test="/UWE4JSF/m2tConfig/contentPackageConfig[modelPackage = $pkg/@name]">
<c:get select="/UWE4JSF/m2tConfig/contentPackageConfig[modelPackage = $pkg/@name]/generate = 'yes' or
/UWE4JSF/m2tConfig/contentPackageConfig[modelPackage = $pkg/@name]/generate = 'true'"/>
<c:otherwise>false</c:otherwise> </c:choose>
</c:set>
<c:if test="$pkg/@generate = 'true'"> <java:package name="{$pkg/@qualifiedName}"
srcFolder="{$org.eclipse.jet.resource.parent.name}/src">
<c:iterate select="$pkg/JavaPackage" var="pkg"> <c:include template="templates/javaPackage.jet"/>
</c:iterate>
<c:iterate select="$pkg/JavaClass" var="cl">
<java:class name="{$cl/@name}" template="templates/contentClass.jet"/> </c:iterate>
<c:iterate select="$pkg/Enumeration" var="enum">
<java:class name="{$enum/@name}" template="templates/enumeration.jet"/> </c:iterate>
<c:iterate select="$pkg/JavaInterface" var="interface">
<java:class name="{$interface/@name}" template="templates/javaInterface.jet"/> </c:iterate>
</java:package> </c:if>
UWE4JSF còn gồm có một sự mở rộng của một vài thẻ JET riêng, được
cung cấp trong một plug-in qua cơ chế mở rộng của Eclipse. Thông thường chúng
được dùng để đơn giản hoá cú pháp các khuôn mẫu. Ngoài ra, JET cho phép tuỳ biến
các thẻ JET đó để dễ dàng triển khai hơn. Với phiên bản hiện tại của UWE4JSF, chỉ có
các thẻ từ thư viện thẻ của UWE4JSF (TagLibrary) được cung cấp. Từ khuôn mẫu
“contentClass.jet” cho ta thấy việc sinh các khai báo kiểu cho các thuộc tính và
các chức năng của lớp Java Bean thông thường. Ví dụ, thẻ <uwejsf:getType> sinh
khai báo kiểu cho các hàm get/set từ thành phần của mô hình UWE4JSF đầu vào
contentClass.jet
<c:iterate select="$cl/Attribute[not(@evaluationExpression)]" var="attribute"> public <uwejsf:getType select="$attribute/type"
basePackage="{/uwejsf/m2tConfig/basePackage}"/> get<c:get select="uppercaseFirst($attribute/@name)"/>() {
return <c:get select="$attribute/@name"/>; }
public void set<c:get select="uppercaseFirst($attribute/@name)"/>(<uwejsf:getType select="$attribute/type" basePackage="{/uwejsf/m2tConfig/basePackage}"/> <c:get select="$attribute/@name"/>) {
this.<c:get select="$attribute/@name"/> = <c:get select="$attribute/@name"/>;
} </c:iterate>
Ở khía cạnh khác, ứng dụng của các thẻ tuỳ biến từ UWE4JSF là xử lý của
ngôn ngữ diễn tả UEL/OGNL từ mô hình UWE-PIM, mà cụ thể là từ mô hình
biểu diễn (presentation model). Để lấy thông tin từ ngôn ngữ diễn tả thì trong
chuyển đổi UWE2JSF (M2T) thẻ JET <uwejsf:getExpression> được sử dụng để
thực hiện nhiệm vụđó. jsfComponent.jet <cc:if test="$component/valueExpression"> value="<uwejsf:getExpression select="$component/valueExpression" forJSF="true"/>" </cc:if>
Như vậy ở mục này luận văn đã đề cập một cách chi tiết đến các khía cạnh
chuyển đổi trong chuyển đổi mô hình sang mã nguồn (M2T), từđó giúp độc giả hiểu
được nguyên lý hoạt động và công nghệ sử dụng trong chuyển đổi M2T, việc này sẽ
tạo các yếu tố như mã nguồn, file cấu hình, vân vân, hoạt động trên khung ứng dụng
UWE4JSF sẽđược mô tả tiếp sau đây.