Zbiory i kontenery właściwości

W platformie jAgE istnieją dwa rodzaje klas przechowujących właściwości i metadane: zbiory i kontenery. Zbiory właściwości, implementujące interfejs IPropertiesSet, są prostymi pojemnikami, które umożliwiają szybki dostęp do właściwości na podstawie ich nazw. Domyślną implementacją jest klasa PropertiesSet, oparta o słownik haszujący. Jest ona serializowalna, dzięki czemu może być użyta w mechanizmie zapytań.

Kontenery także przechowują właściwości, jednak oprócz tego dostarczają dodatkową funkcjonalność:

  1. Obsługują złożone właściwości - w przeciwieństwie do zbiorów, kontenery umożliwiają dostęp do właściwości przy pomocy ścieżki, a nie tylko nazwy.
  2. Współpracują z omówionymi w dalszej części funkcjami właściwości.
  3. Kontenery umożliwiają monitorowanie właściwości prostych i złożonych.

Podstawowym kontenerem właściwości jest klasa ClassPropertyContainer, będąca klasą bazową dla wszystkich agentów.

Poniższy diagram przedstawia klasy kontenerów i zbiorów oraz zależności pomiędzy nimi:

Wczytywanie definicji właściwości

Aby zmniejszyć zużycie pamięci dla obiektów, które nie korzystają z właściwości, są one wczytywane dopiero po pierwszym wywołaniu jakiejkolwiek metody, która z nich korzysta (lazy loading). Klasa ClassPropertyContainer zleca wyszukiwanie wszystkich właściwości (oraz meta-właściwości) innemu obiektowi, implementującemu interfejs IClassPropertiesFactory. Definicje tych klas oraz przebieg sterowania podczas ładowania właściwości jest przedstawiony na poniższym diagramie:

Domyślna implementacja, ClassAnnotatedPropertiesFactory, potrafi znaleźć wszystkie właściwości zdefiniowane w klasie przy pomocy adnotacji pól lub metod odczytujących i zapisujących wartość. Jest ona zaimplementowana tak, aby dla każdej klasy sprawdzała adnotowane pola i metody tylko raz, i wykorzystywała znalezione informacje. Fabrykę właściwości można zmieniać przez przedefiniowanie metody
getPropertiesFactory klasy ClassPropertyContainer.
Metoda getMetaProperties klasy ClassPropertyContainer umożliwia dostęp do metadanych bez konieczności ładowania wszystkich właściwości, dlatego powinna być wykorzystywana zamiast wywołania
getProperties().getMetaPropertiesSet().

Ścieżki do właściwości złożonych

Gramatyka dla ścieżek właściwości jest następująca:

path -> ( '.' arrayIdentifier )* identifier;
arrayIdentifier -> identifier arrayIndex*;
identifier -> dowolny niepusty ciąg sybmoli, które nie należą do zbioru: '[', ']', '.', '@', '*'
arrayIndex -> '[' number ']';
number -> dowolny niepusty ciąg cyfr

Za parsowanie ścieżek do właściwości złożonych odpowiedzialna jest klasa PropertyPathParser, z której korzysta kontener ClassPropertyContainer. Klasa ta, przedstawiona na poniższym diagramie, jest zaimplementowana jako prosty parser LL(1). Każda instancja parsera jest ściśle powiązana z pojedynczym kontenerem (root), od którego rozpoczyna poszukiwanie właściwości dla analizowanej ścieżki.