Opis pliku kontraktu XML
Poniżej pokazane są fragmenty pliku kontraktu XML dla klasy AdvancedExampleComponent
dziedziczącej po SimpleExampleComponent
, która również posiada swój kontrakt XML. Pliki XML z opisem klasy muszą mieć nazwę w formacie <NazwaKlasy>.contract.xml i należeć do tego samego pakietu co opisywana klasa. Wynika to z faktu, że są one ładowane wykorzystując getResourceAsStream na klasie komponentu.
Opis pliku kontraktu na przykładzie AdvancedExampleComponent.contract.xml
<component>
jest głównym elementem struktury XML. Wymagany atrybut class
określa jakiej klasy dotyczy opis. Wymagany atrybut version
określa wersję komponentu.
<component class="org.jage.property.xml.testHelpers.AdvancedExampleComponent" version="1.0.0" xmlns="org.jage" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="org.jage ageDependency.xsd">
<extends>
określa po jakim komponencie dziedziczy komponent opisywany. W pliku XML może znajdować się co najwyżej jeden taki element. Atrybut class
zawiera pełną nazwę klasy nadrzędnej i jest wymagany. Atrybut version
określa wersję klasy nadrzędnej. Jeżeli w pliku kontraktu uwzględnimy ten element, to klasa rodzica także musi mieć swój plik kontraktu
<extends class="org.jage.property.xml.testHelpers.SimpleExampleComponent" version="1.0.0" />
<implements>
określa jakie interfejsy implementuje dany komponent. Atrybut class
zawiera pełną nazwę implementowanego interfejsu i jest wymagany. Atrybut version
określa wersję implementowanego interfejsu. Element ten nie jest wymagany, jeśli klasa nie implementuje specyficznego interfejsu.
<implements class="org.jage.strategy.IStrategy" version="3.2.1" />
<requires>
określa od jakich komponentów może zależeć opisywany komponent. Atrybut class
zawiera pełną nazwę wymaganej klasy i jest obowiązkowy. Atrybut version
określa wersję wymaganego komponentu. Element można pominąć, jeśli poprawne działanie komponentu nie zależy od innych.
<requires class="org.jage.component.AnotherSimpleExampleComponent" version="1.2.4"/>
<declaration>
to część zawierająca opis atrybutów komponentu. W pliku XML musi znajdować się dokładnie jeden taki element, choć może być pusty.
<declaration>
<attribute>
opisuje atrybut klasy. Wymagane atrybuty:
name
- nazwa atrybutu,access
- określa sposób dostępu do atrybutu ("direct"/"setter"),required
- określa czy wymagane jest ustawianie wartości atrybutu (aktualnie nieobsługiwane).- atrybuty
setter
igetter
służą do podania nazw settera i gettera dla danego atrybutu, gdy parametraccess
jest ustawiony na "setter". Jeżeli nazwy settera i gettera są standardowe (czyli w formacie set/get|<CapitalizedFirstLetterOfAttributeName>, np. setMyAttribute dla atrybutu myAttribute), to można pominąć podawanie nazw settera i gettera. - atrybut
fieldName
służy do podania nazwy pola odpowiadającego danemu atrybutowi, gdy parametraccess
jest ustawiony na "direct". Jeżeli nazwa pola jest taka sama jak nazwa atrybutu, to można pominąć podawanie nazwy pola.
Istnieje jeszcze opcjonalny atrybutmodifier
określający modyfikator dostępu. zobacz tutaj
<attribute access="direct" modifier="1" name="array" required="true"> <type> <array dims="3"> <type> <primitive name="int"/> </type> </array> </type> </attribute> <attribute access="direct" modifier="0" name="map" required="true"> <type> <parametrized class="interface java.util.Map"> <type> <simpleClass>java.lang.String</simpleClass> </type> <type> <simpleClass>java.lang.Integer</simpleClass> </type> </parametrized> </type> </attribute> <attribute access="setter" modifier="2" name="intProperty" fieldName="_intProperty" required="true" getter="getIntProperty" setter="setIntProperty"> <type> <primitive name="int"/> </type> </attribute>
- element
<type>
, którego strukturę najlepiej opisuje poniższy rysunek. Wewnątrz elementu<type>
może się znajdować dokładnie jeden z elementów<primitive>
,<simpleClass>
,<array>
albo<parametrized>
.
<primitive>
zawiera atrybut obowiązkowy name
definiujący typ prymitywny (np. int, boolean) i opcjonalny value
definiujący domyślną wartość (aktualnie nie jest wykorzystywany).
<simpleClass>
jest elementem prostym. Wewnątrz niego należy podać pełną nazwę klasy.
<parametrized>
służy do opisu klas parametryzowanych (m.in. kolekcji i map). Atrybut class
określa z jaką klasą mamy do czynienia. Zagnieżdżone elementy <type>
i <wildcard>
określają typy klas "wewnętrznych". <wildcard>
to specjalny typ dla parametrów <?>
, <? extends T>
i <? implements T>
. <upper>
i <lower>
określają górne i dolne ograniczenie w hierarchii dziedziczenia. zobacz tutaj
Dodatkowo <simpleClass>
i <parametrized>
posiadają opcjonalne parametry interface
(typu boolean) i special
(przyjmuje jedną z wartości: "list", "set" lub "map"). Pierwszy z nich wskazuje czy "klasa" podana w atrybucie class
jest interfejsem. Drugi wskazuje, że mamy do czynienia z listą, zbiorem lub mapą. Oba parametry zostały przygotowane na potrzeby przyszłych potrzeb i aktualnie nie są wykorzystywane.
Poniżej widać opis atrybutu o nazwie list
będącego listą Stringów.
<attribute access="direct" modifier="0" name="list" required="true"> <type> <parametrized class="class java.util.ArrayList" special="list"> <type> <simpleClass>java.lang.String</simpleClass> </type> </parametrized> </type> </attribute>
Poniżej widać opis atrybutu o nazwie map
będącego mapą z kluczami typu String i wartościami typu Integer.
<attribute access="direct" modifier="0" name="map" required="true"> <type> <parametrized class="java.util.Map" interface="true" special="map"> <type> <simpleClass>java.lang.String</simpleClass> </type> <type> <simpleClass>java.lang.Integer</simpleClass> </type> </parametrized> </type> </attribute>
Poniżej widać opis atrybutu o nazwie SClass
typu <? super Integer>
.
<attribute access="direct" modifier="2" name="SClass" required="true"> <type> <parametrized class="class java.lang.Class"> <wildcard> <lower> <type> <simpleClass>java.lang.Integer</simpleClass> </type> </lower> <upper> <type> <simpleClass>java.lang.Object</simpleClass> </type> </upper> </wildcard> </parametrized> </type> </attribute>
<array>
służy do definiowania tablic. Atrybut dims
określa wymiarowość tablicy, a zagnieżdżony element <type>
typ elementów tablicy.
Poniżej widać przykład trójwymiarowej tablicy intów.
<attribute access="direct" modifier="1" name="array" required="true"> <type> <array dims="3"> <type> <primitive name="int"/> </type> </array> </type> </attribute>