Projekt zakończony
Maciej Dudek (4AR) md5@o2.pl
ARD
GEF and Eclipse based editor for ARD and XTT. Evaluation, feasibility, prototype. XTTv2 Editor requirements
Feasibility study, a description how to create such editors with GEF, a prototype editor MS Thesis regarding GEF: Interfejs graficzny do budowy aplikacji komponentowych zapewniający weryfikację semantyczną, ARD+ Editor requirements
Swoją pracę rozpocząłem od lektury następujących prac:
Dalsze kroki to:
Ponieważ skróty EMF, GEF i GMF są do siebie podobne, po krótce wyjaśnię między różnice między tymi frameworkami:
Zatem tworząc aplikację z pewnością użycie wszystkich z nich będzie nieodzowne a ich działanie będzie się przenikało.
Aby skorzystać z możliwości EMF importując model XSD, przekształcono definicję HML.dtd z postaci DTD do postaci XSD. Efekt został przedstawiony poniżej:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> <xs:element name="hml"> <xs:complexType> <xs:sequence> <xs:element ref="type_set"/> <xs:element ref="attribute_set"/> <xs:element minOccurs="0" ref="property_set"/> <xs:element minOccurs="0" ref="tph"/> <xs:element minOccurs="0" ref="ard"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="type_set"> <xs:complexType> <xs:sequence> <xs:element minOccurs="0" maxOccurs="unbounded" ref="type"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="type"> <xs:complexType> <xs:sequence> <xs:element minOccurs="0" ref="desc"/> <xs:element ref="domain"/> </xs:sequence> <xs:attribute name="id" use="required" type="xs:ID"/> <xs:attribute name="name" use="required"/> <xs:attribute name="base" use="required"> <xs:simpleType> <xs:restriction base="xs:token"> <xs:enumeration value="integer"/> <xs:enumeration value="numeric"/> <xs:enumeration value="string"/> <xs:enumeration value="bool"/> <xs:enumeration value="date"/> <xs:enumeration value="time"/> <xs:enumeration value="timestamp"/> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute name="length"/> <xs:attribute name="scale"/> </xs:complexType> </xs:element> <!-- id should begin with 'tpe_...' --> <xs:element name="desc" type="xs:string"/> <xs:element name="domain"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element ref="range"/> <xs:element ref="value"/> </xs:choice> <xs:attribute name="type"> <xs:simpleType> <xs:restriction base="xs:token"> <xs:enumeration value="ordered"/> <xs:enumeration value="unordered"/> </xs:restriction> </xs:simpleType> </xs:attribute> </xs:complexType> </xs:element> <xs:element name="range"> <xs:complexType> <xs:attribute name="from" use="required"/> <xs:attribute name="to" use="required"/> </xs:complexType> </xs:element> <xs:element name="value" type="xs:string"/> <xs:element name="attribute_set"> <xs:complexType> <xs:sequence> <xs:element minOccurs="0" maxOccurs="unbounded" ref="att"/> <xs:element minOccurs="0" maxOccurs="unbounded" ref="group"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="att"> <xs:complexType> <xs:sequence> <xs:element minOccurs="0" ref="desc"/> </xs:sequence> <xs:attribute name="id" use="required" type="xs:ID"/> <xs:attribute name="type" type="xs:IDREF"/> <xs:attribute name="name" use="required"/> <xs:attribute name="abbrev"/> <xs:attribute name="value" use="required"> <xs:simpleType> <xs:restriction base="xs:token"> <xs:enumeration value="single"/> <xs:enumeration value="multiple"/> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute name="class" use="required"> <xs:simpleType> <xs:restriction base="xs:token"> <xs:enumeration value="ro"/> <xs:enumeration value="rw"/> <xs:enumeration value="wo"/> <xs:enumeration value="state"/> </xs:restriction> </xs:simpleType> </xs:attribute> </xs:complexType> </xs:element> <!-- id should begin with 'att_...' --> <xs:element name="group"> <xs:complexType> <xs:sequence> <xs:element minOccurs="0" ref="desc"/> <xs:element maxOccurs="unbounded" ref="attref"/> </xs:sequence> <xs:attribute name="id" use="required" type="xs:ID"/> <xs:attribute name="name" use="required"/> <xs:attribute name="abbrev"/> </xs:complexType> </xs:element> <!-- id should begin with 'grp_...' --> <xs:element name="attref"> <xs:complexType> <xs:attribute name="ref" use="required" type="xs:IDREF"/> </xs:complexType> </xs:element> <xs:element name="property_set"> <xs:complexType> <xs:sequence> <xs:element minOccurs="0" maxOccurs="unbounded" ref="property"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="property"> <xs:complexType> <xs:sequence> <xs:element maxOccurs="unbounded" ref="attref"/> </xs:sequence> <xs:attribute name="id" use="required" type="xs:ID"/> </xs:complexType> </xs:element> <!-- id should begin with 'prp_...' --> <xs:element name="tph"> <xs:complexType> <xs:sequence> <xs:element minOccurs="0" maxOccurs="unbounded" ref="trans"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="trans"> <xs:complexType> <xs:attribute name="src" use="required" type="xs:IDREF"/> <xs:attribute name="dst" use="required" type="xs:IDREF"/> </xs:complexType> </xs:element> <xs:element name="ard"> <xs:complexType> <xs:sequence> <xs:element minOccurs="0" maxOccurs="unbounded" ref="dep"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="dep"> <xs:complexType> <xs:attribute name="independent" use="required" type="xs:IDREF"/> <xs:attribute name="dependent" use="required" type="xs:IDREF"/> </xs:complexType> </xs:element> </xs:schema>
Dokument hml-test.xml poprawnie przechodzi walidację przy użyciu powyższej definicji. Konwersji dokonano przy użyciu programu Trang.
Powyższa definicja, choć poprawna, okazała się niekompatybilna z frameworkiem GMF. Podstawowe problemy to:
Dokonano próby utworzenia edytora wszystkich elementów (bez żadnej customizacji) za pomocą pluginu do GMF o nazwie Dynamic GMF. Ten plugin ma w założeniu dać możliwość wygenerowania edytora jedynie przez wybranie pliku xsd. Pojawiał się jednak błąd wewnętrzny programu „Null pointer exception”. Takiego błędu nie było gdy użyłem pliku mindmap.xsd. Sądzę, iż obecność elementów IDREF mogła się do tego przyczynić.
Dużo bardziej naturalnym, prostszym i efektywniejszym sposobem jest tworzenie modelu ecore pasującego do GMF. I tak import z XSD następuje do pliku ECORE, na którym później się operuje.
Kolejnym krokiem mogłoby być eksportowanie tego modelu do XSD. W razie potrzeby można by dokonywać konwersji między róznymi definicjami XSD za pomocą szablonów XSLT.
Stworzyłem zatem edytor opierając się o własny model. Model powstał przy pomocy EMF, który następnie wyeksportowałem do formatu XSD.
Nowa wersja Ard.xsd:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <xsd:schema xmlns:hml="hml" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="hml"> <xsd:element name="Ard" type="hml:Ard"/> <xsd:element name="Property" type="hml:Property"/> <xsd:element name="Atrybut" type="hml:Atrybut"/> <xsd:complexType name="Ard"> <xsd:sequence> <xsd:element maxOccurs="unbounded" minOccurs="0" name="property" type="hml:Property"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="Property"> <xsd:sequence> <xsd:element maxOccurs="unbounded" minOccurs="0" name="atrybut" type="hml:Atrybut"/> </xsd:sequence> <xsd:attribute name="dependant"> <xsd:simpleType> <xsd:list itemType="xsd:anyURI"/> </xsd:simpleType> </xsd:attribute> </xsd:complexType> <xsd:complexType name="Atrybut"> <xsd:attribute name="nazwa"/> </xsd:complexType> </xsd:schema>
Niestety, zawiera on jedynie opis ARD, bez TPH ani XTT.
Poniżej zamieszczono screen z edytora oraz odpowiadający mu plik xml.
Diagram Ard
Wygenerowany plik XML:
<?xml version="1.0" encoding="UTF-8"?> <hml:Ard xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:hml="hml"> <property dependant="//@property.1 //@property.2"> <atrybut nazwa="jeden"/> <atrybut nazwa="dwa"/> </property> <property> <atrybut nazwa="trzy"/> <atrybut nazwa="cztery"/> </property> <property> <atrybut nazwa="pięć"/> <atrybut nazwa="sześć"/> </property> </hml:Ard>
Sprawdzono zgodność pliku xml ze schematem xsd.
Możliwości edytora ważne z punktu widzenia ARD:
Jest to wstępny zarys edytora. Docelowy edytor miałby posiadać bogatą funkcjonalność. Dalsze elementy, które należałoby zaimplementować to:
Poniżej zamieszczam wartościowe linki związane z moim projektem:
Problemy, które napotkałem oraz linki pomocne w ich rozwiązaniu:
GEF resources (GEF, http://www.eclipse.org/articles/Article-GEF-editor/gef-schema-editor.html),
Patrz też na osobne hasło