Здравствуйте, не могу найти ссылку на скачивание курса «Визуальное моделирование: теория и практика»
Номер платежа 6400454020565 |
Пример предметно-ориентированного визуального языка
Служебный синтаксис
Как обсуждалось в предыдущей лекции, служебный синтаксис визуального языка задает формат хранения графа модели. Этот формат приято задавать в виде XML-схемы, которой должны соответствовать XML-документы с описаниями конкретных визуальных моделей. Подробную информацию о XML можно получить в [12.8], [12.9], [12.10], а ниже будут представлены XML-спецификации для нашего примера, снабженные необходимыми комментариями.
XML-схема в формате XML Schema для SCL выглядит следующим образом.
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault= "qualified" attributeFormDefault="unqualified"> <xs:complexType name="model"> <xs:sequence> <xs:element name="component" type="component" maxOccurs="unbounded"/> <xs:element name="signal_list" type="signal_list" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:complexType name="signal_list"> <xs:sequence> <xs:element name="signal" type="signal" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:complexType name="component"> <xs:sequence> <xs:element name="attribute" type="attribute" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="method" type="method" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="statechart" type="statechart" minOccurs="0" maxOccurs="1"/> </xs:sequence> <xs:attribute name="name" type="xs:string"/> <xs:attribute name="init" type="xs:string"/> <xs:attribute name="num" type="xs:string"/> </xs:complexType> <xs:complexType name="signal"> <xs:attribute name="name" type="xs:string"/> </xs:complexType> <xs:complexType name="attribute"> <xs:attribute name="name" type="xs:string"/> <xs:attribute name="type" type="xs:string"/> </xs:complexType> <xs:complexType name="method"> <xs:attribute name="name" type="xs:string"/> </xs:complexType> <xs:complexType name="statechart"> <xs:sequence> <xs:element name="state" type="state" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:complexType name="state"> <xs:sequence> <xs:element name="transition" type="transition" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute name="name" type="xs:string"/> </xs:complexType> <xs:complexType name="transition"> <xs:sequence> <xs:element name="input" type="input" minOccurs="0"/> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="send" type="send"/> <xs:element name="handle_invocation" type="handle_invocation"/> </xs:choice> </xs:sequence> <xs:attribute name="target_state_ref" type="xs:string"/> </xs:complexType> <xs:complexType name="input"> <xs:attribute name="signal_ref" type="xs:string"/> </xs:complexType> <xs:complexType name="action"/> <xs:complexType name="send"> <xs:complexContent> <xs:extension base="action"> <xs:attribute name="signal_ref" type="xs:string"/> </xs:extension> </xs:complexContent> </xs:complexType> <xs:complexType name="handle_invocation"> <xs:complexContent> <xs:extension base="action"> <xs:attribute name="method_ref" type="xs:string"/> </xs:extension> </xs:complexContent> </xs:complexType> <xs:element name="model" type="model"/> </xs:schema>Листинг 12.1.
Любая XML-спецификация - и схема, и документ - состоит из тегов, каждый из которых имеет имя, набор атрибутов, а также может включать в себя другие теги. Каждый тег имеет начало и конец. Теги образуют древовидную иерархию, вкладываясь друг в друга.
Будем называть теги в XML-схеме тегами-типами, а в XML-документе - тегами-значениями. Тег-типы задают структуру XML-документов. А XML-документ состоит из тегов-значений - экземпляров тего-типов.
В данном примере и абстрактный, и служебный синтаксис имеют одну и ту же структуру. Чтобы этого достичь, я предусмотрительно позаботился при создании метамодель о том, чтобы каждый класс агрегировался ровно один раз другим классом – непосредственно или косвенно, через "предка" по иерархии наследования. То есть классы метамодели составляют древовидную иерархию, которую легко отобразить средствами XML. Если же метамодель не будет иметь подобную структуру, то XML-схема будет на нее похожа значительно меньше, чем в этом примере.
XML-схема, задающая структуру XML-документов с SCL-моделями, устроена так. Сначала идет заголовок с некоторой служебной информацией. Далее следует описание тегов-типов. Теги-типы верхнего уровня вложенности имеют тип complexType. Каждый из них соответствует некоторому классу метамодели и имеет свойство name, задающее его имя – component, signal, attribute и т.д. Далее идет список атрибутов, если эти атрибуты имеются у соответствующего класса в метамодели. Каждый атрибут задается специальным тегом-типом attribute, в котором через свойство name задается имя атрибута, а через свойство type – его тип. Все типы в данном примере являются строковыми (string).
Теги-типы complexType в XML-схеме должны быть связаны друг с другом, как связаны соответствующие им классы метамодели. На уровень XML-схемы попадает агрегирование и наследование, ассоциации задаются через ссылки по имени. Для задания агрегирования используются теги-типы sequence/element, для задания наследования – choice/element и complexContent/extension.
Тег-тип sequence определяет, что в этом месте в XML-документе должна идти некоторая последовательность фрагментов текста. Тип каждого фрагмента задается тегом-типом element. Свойства minOccurs и maxOccurs у element задают множественность вхождений фрагментов данного типа – нижнюю и верхнюю границу соответственно. Если minOccurs отсутствует, значит, минимальное количество таких фрагментов равно единице. Свойство type у element указывает тип фрагмента текста. В нашем случае это ссылка на некоторый тег-тип complexType. Ссылка реализована по имени. Тег-тип sequence задает порядок вхождений типизированных фрагментов текста. Например, если компонента была в sequence прежде списка сигналов, то в XML- документе, как можно видеть ниже, сначала идут все компоненты ( Client, Server, Monitor ), а потом единственный список сигналов. Таким образом, пара sequence/element реализует агрегирование.
Теги-типы choice/element и complexContent/extension нужны для задания наследования. Вспомним рис. 12.3 – класс transition агрегирует класс action (переход может включать в себя много действий), а последний является предком для классов send и handle_invocation. В XML-схеме это задается так. У тега-типа transition в sequence входит один элемент типа input (и тут все понятно), а далее можно увидеть тег-тип choice. Он заменяет собой класс action и имеет множественность 0..*, как и у action. Тег-тип choice включает в себя два тега-типа element – для send и handle_invocation. Фрагменты текста, заданные двумя последними тегами, могут идти в произвольном порядке. Далее определяется тег-тип action и теги-типы send и handle_invocation, которые строятся на основе action. Это "строительство" происходит так: в каждом из них заводится тег-тип complexContent, который означает, что далее внутри идет некоторая сложная структура, сложнее тех тегов-типов, что нам встречались до сих пор – атрибутов, выборов и последовательностей (теги-типы attribute, sequence, сhoice ). Внутри complexContent определяется включение action с расширением. Это делается с помощью тега-типа extension. Текст, задаваемый action, вставляется вместо конструкции extension и расширяется дополнительным текстом – ссылкой на сигнал или ссылкой на метод для send/handle_method соответственно.
Ниже приводится соответствующий этой схеме XML-документ для графа модели, заданного на рис. 12.1. В таком виде информация о визуальной модели сохраняется на жестком диске.
<?xml version="1.0" encoding="UTF-8"?> <model> <component name="Client"> <method name="Init"/> <method name="RejectHandle"/> <method name="AcceptHandle"/> </component> <component name="Server"> <method name="Init"/> <method name="AcceptHandler"/> <method name="TerminateHandler"/> <statechart> <state name="Start"> <transition target_state_ref="Idle"> <handle_invocation method_ref="Init"/> </transition> </state> <state name="End"> </state> <state name="Idle"> <transition target_state_ref="End"> <input signal_ref="Terminate"/> <handle_invocation method_ref="TerminateHandle"/> </transition> <transition target_state_ref="Wait"> <input signal_ref="Request"/> <handle_invocation method_ref="Respond"/> </transition> </state> <state name="Wait"> <transition target_state_ref="Idle"> <input signal_ref="Info1"/> <handle_invocation method_ref="AcceptHandle"/> </transition> <transition target_state_ref="Idle"> <input signal_ref="Info2"/> <handle_invocation method_ref="Reject"/> </transition> </state> </statechart> </component> <component name="Monitor"> <method name="CreateClient"/> <method name="CreateServer"/> <method name="TerminateClient"/> <method name="TerminateServer"/> </component> <signal_list> <signal name="Request"/> <signal name="Respond"/> <signal name="Info1"/> <signal name="Info2"/> <signal name="Accept"/> <signal name="Reject"/> <signal name="Terminate"/> </signal_list> </model>Листинг 12.2.